Skip to content

Commit

Permalink
Merge pull request #26 from utmgdsc/feature/54/metrics-history
Browse files Browse the repository at this point in the history
Feature/54/metrics history
  • Loading branch information
Yazan10x authored Nov 25, 2023
2 parents a53d2b3 + e34f3f8 commit a1c1eb6
Show file tree
Hide file tree
Showing 28 changed files with 1,200 additions and 574 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
*.iml
*.DS_Store
node_modules
.venv
.venv
backend/.migrations
100 changes: 100 additions & 0 deletions .idea/shelf/Uncommitted_changes_before_rebase_[Changes]/shelved.patch

Large diffs are not rendered by default.

20 changes: 15 additions & 5 deletions backend/app.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# Python Imports
from flask import Flask, render_template
from bson import ObjectId
from flask import Flask, Response, jsonify, render_template
from flask_cors import CORS

# Imports
from routes.users import users
from routes.transportation import transportation_service

from utils.customJSONEncoder import CustomJSONProvider

app = Flask(__name__)
app.json = CustomJSONProvider(app)

# Services
app.register_blueprint(users, url_prefix="/users")
Expand All @@ -16,8 +18,8 @@


@app.route("/")
def home() -> str:
return 'Carbon Track APP BACKEND API :: UNAUTHORIZED ACCESS'
def home() -> Response:
return jsonify('Carbon Track APP BACKEND API :: UNAUTHORIZED ACCESS')


# This is just for testing
Expand All @@ -26,6 +28,14 @@ def test_google() -> str:
return render_template('index.html')


@app.route('/get_object_id')
def get_object_id():
# Example: Creating an ObjectId
my_object_id = ObjectId()

return jsonify({'_id': my_object_id})


if __name__ == '__main__':

app.run(host='0.0.0.0', port=6050, debug=True)
app.run(host='0.0.0.0', port=6050, debug=True, threaded=False)
2 changes: 1 addition & 1 deletion backend/models/abstract_db_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class DB_MODEL:
def __init__(self, oid: ObjectId) -> None:
self.oid = ObjectId(oid)

def to_json(self, for_mongodb: bool = False) -> json:
def to_json(self) -> json:
raise NotImplementedError

@staticmethod
Expand Down
87 changes: 64 additions & 23 deletions backend/models/transportation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
"""

from __future__ import annotations
from typing import Union
import json
from datetime import datetime
from datetime import datetime, timezone
from models.abstract_db_model import DB_MODEL
from bson import ObjectId
from bson import json_util


class TransportationEntry(DB_MODEL):
Expand All @@ -18,11 +18,11 @@ class TransportationEntry(DB_MODEL):
motorbike: int
electric_car: int
gasoline_car: int
carbon_emissions: float
carbon_emissions: int
date: datetime

def __init__(self, oid: ObjectId, user_id: ObjectId, bus: int, train: int, motorbike: int,
electric_car: int, gasoline_car: int, carbon_emissions: float, date: datetime) -> None:
electric_car: int, gasoline_car: int, carbon_emissions: int, date: Union[str, datetime]) -> None:
super().__init__(oid)
self.user_id = ObjectId(user_id)
self.bus = bus
Expand All @@ -31,29 +31,30 @@ def __init__(self, oid: ObjectId, user_id: ObjectId, bus: int, train: int, motor
self.electric_car = electric_car
self.gasoline_car = gasoline_car
self.carbon_emissions = carbon_emissions
self.date = date
if isinstance(date, datetime):
self.date = date
else:
self.date = datetime.fromisoformat(date)

def to_json(self, for_mongodb: bool = False) -> json:
def to_json(self) -> json:
res = {
'_id': self.oid,
'user_id': self.user_id,
'bus': self.bus,
'train': self.train,
'motorbike': self.motorbike,
'electric_car': self.electric_car,
'gasoline_car': self.gasoline_car,
'carbon_emissions': self.calculate_carbon_emissions(),
'date': self.date
"_id": self.oid,
"user_id": self.user_id,
"bus": self.bus,
"train": self.train,
"motorbike": self.motorbike,
"electric_car": self.electric_car,
"gasoline_car": self.gasoline_car,
"carbon_emissions": self.calculate_carbon_emissions(),
"date": self.date
}
if for_mongodb:
return res
return json.loads(json_util.dumps(res))
return res

@staticmethod
def from_json(doc: json) -> TransportationEntry:
return TransportationEntry(
oid=ObjectId(doc["_id"]),
user_id=doc['user_id'],
user_id=ObjectId(doc["user_id"]),
bus=doc["bus"],
train=doc["train"],
motorbike=doc["motorbike"],
Expand All @@ -63,14 +64,54 @@ def from_json(doc: json) -> TransportationEntry:
date=doc["date"]
)

def calculate_carbon_emissions(self) -> float:
def calculate_carbon_emissions(self) -> int:
bus_carbon_emissions = self.bus * 0.103
train_carbon_emissions = self.train * 0.037
motorbike_carbon_emissions = self.motorbike * 0.113
electric_car_carbon_emissions = self.electric_car * 0.4
gasoline_car_carbon_emissions = self.gasoline_car * 2.3
return sum([bus_carbon_emissions, train_carbon_emissions, motorbike_carbon_emissions,
electric_car_carbon_emissions, gasoline_car_carbon_emissions])
return int(sum([bus_carbon_emissions, train_carbon_emissions, motorbike_carbon_emissions,
electric_car_carbon_emissions, gasoline_car_carbon_emissions]))

@staticmethod
def get_monthly_view(start: datetime, end: datetime,
transportationEntries: list[TransportationEntry]) -> list[dict[str, Union[list[float], str]]]:
monthly_data = []

# Make start date offset-aware (assuming UTC for simplicity)
start = start.replace(tzinfo=timezone.utc)

current_month = start
while current_month <= end:
# Add the current month to the list
monthly_data.append({
"month": current_month.strftime("%B"),
"year": current_month.strftime("%Y"),
"data": [0, 0, 0, 0]
})

# Move to the next month
if current_month.month == 12:
current_month = datetime(current_month.year + 1, 1, 1, tzinfo=timezone.utc)
else:
current_month = datetime(current_month.year, current_month.month + 1, 1, tzinfo=timezone.utc)

for transportation_entry in transportationEntries:
for monthly_entry in monthly_data:
if transportation_entry.date.strftime("%B") == monthly_entry["month"] \
and transportation_entry.date.strftime("%Y") == monthly_entry["year"]:
if transportation_entry.date.day < 7:
monthly_entry["data"][0] = transportation_entry.calculate_carbon_emissions()
elif transportation_entry.date.day < 14:
monthly_entry["data"][1] = transportation_entry.calculate_carbon_emissions()
elif transportation_entry.date.day < 21:
monthly_entry["data"][2] = transportation_entry.calculate_carbon_emissions()
elif transportation_entry.date.day < 28:
monthly_entry["data"][3] += transportation_entry.calculate_carbon_emissions()
else: # If a Month has 5 sunday, we add them to the fourth week
monthly_entry["data"][3] += transportation_entry.calculate_carbon_emissions() / 4

return monthly_data

def __repr__(self) -> str:
return f'Transportation ID: {self.oid.__str__()}'
return f"Transportation ID: {self.oid.__str__()}"
7 changes: 2 additions & 5 deletions backend/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import json
from models.abstract_db_model import DB_MODEL
from bson import ObjectId
from bson import json_util


class User(DB_MODEL):
Expand All @@ -25,7 +24,7 @@ def __init__(self, oid: ObjectId, full_name: str, email: str, badges: list[str],
self.friends = friends
self.score = score

def to_json(self, for_mongodb: bool = False) -> json:
def to_json(self) -> json:
res = {
'_id': self.oid,
'full_name': self.full_name,
Expand All @@ -34,9 +33,7 @@ def to_json(self, for_mongodb: bool = False) -> json:
'friends': self.friends,
'score': self.score
}
if for_mongodb:
return res
return json.loads(json_util.dumps(res))
return res

@staticmethod
def from_json(doc: json) -> User:
Expand Down
90 changes: 63 additions & 27 deletions backend/postman/Backend.postman_collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,14 @@
}
},
"url": {
"raw": "{{LocalBaseURL}}/transportation/transportation/651cf22c1d4f7834e2303a44",
"raw": "{{LocalBaseURL}}/transportation/transportation/655d5c7d123217b52115b046",
"host": [
"{{LocalBaseURL}}"
],
"path": [
"transportation",
"transportation",
"651cf22c1d4f7834e2303a44"
"655d5c7d123217b52115b046"
]
}
},
Expand All @@ -177,16 +177,6 @@
"disableBodyPruning": true
},
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjBkMGU4NmJkNjQ3NDBjYWQyNDc1NjI4ZGEyZWM0OTZkZjUyYWRiNWQiLCJ0eXAiOiJKV1QifQ.eyJuYW1lIjoiWWF6YW4gQXJtb3VzaCIsInBpY3R1cmUiOiJodHRwczovL2xoMy5nb29nbGV1c2VyY29udGVudC5jb20vYS9BQ2c4b2NKMThLbUhSTDY3d2NHNDZLNDhaVF9RN0RVbExyN25rOHhJQ2s1S0VNZExVRW9xPXM5Ni1jIiwiaXNzIjoiaHR0cHM6Ly9zZWN1cmV0b2tlbi5nb29nbGUuY29tL2NhcmJvbi10cmFjay1zeXN0ZW0iLCJhdWQiOiJjYXJib24tdHJhY2stc3lzdGVtIiwiYXV0aF90aW1lIjoxNjk4NTMwMzE3LCJ1c2VyX2lkIjoiUkZSbmdJVm1Bd1BHY0pxVFVPalZOeFB4SzVzMSIsInN1YiI6IlJGUm5nSVZtQXdQR2NKcVRVT2pWTnhQeEs1czEiLCJpYXQiOjE2OTg1MzAzMTcsImV4cCI6MTY5ODUzMzkxNywiZW1haWwiOiJ5YXphbi5hcm1vdXNoMUBnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiZmlyZWJhc2UiOnsiaWRlbnRpdGllcyI6eyJnb29nbGUuY29tIjpbIjExNzEyOTg2MDYwMzg2MDUxODQwOCJdLCJlbWFpbCI6WyJ5YXphbi5hcm1vdXNoMUBnbWFpbC5jb20iXX0sInNpZ25faW5fcHJvdmlkZXIiOiJnb29nbGUuY29tIn19.D586V3FjImF4P46sjEw1VuwgHXY5VTHPPrQAzC1thWqe5rASSYqxPRtn53xCD8_mxAzNjPu5zmGLmuiW0AL3x8hs4KiB8jhGlcx_z32mfDOBqvhlqgJw6HEsQRj7kziPvD1gnTt0I4xVuculKFSY6gYeyoii6_A6fN4frqoR59qzb4iNDXnHaKovleUB9VWmzG1cLcvzSP1nXSvj8tNIR_e52yTPq9tpAf-hkzs_1dTS3a65canzVOW_F6plnX79TZJ5N9Wvm7669cX8v2qUb-e5gBkMnU2i70jjheacaXVuHx_cb-JIK12VpmrsVfJGSD_uwCfODHf140lfdr_okg",
"type": "string"
}
]
},
"method": "GET",
"header": [],
"body": {
Expand All @@ -199,57 +189,93 @@
}
},
"url": {
"raw": "{{LocalBaseURL}}/transportation/get_transportation_metric_for_today/655151e8875bab2e6811b8b8",
"raw": "{{LocalBaseURL}}/transportation/get_transportation_metric_for_today",
"host": [
"{{LocalBaseURL}}"
],
"path": [
"transportation",
"get_transportation_metric_for_today",
"655151e8875bab2e6811b8b8"
"get_transportation_metric_for_today"
]
}
},
"response": []
},
{
"name": "Get Current Transportation Copy",
"name": "Date Range",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjBkMGU4NmJkNjQ3NDBjYWQyNDc1NjI4ZGEyZWM0OTZkZjUyYWRiNWQiLCJ0eXAiOiJKV1QifQ.eyJuYW1lIjoiWWF6YW4gQXJtb3VzaCIsInBpY3R1cmUiOiJodHRwczovL2xoMy5nb29nbGV1c2VyY29udGVudC5jb20vYS9BQ2c4b2NKMThLbUhSTDY3d2NHNDZLNDhaVF9RN0RVbExyN25rOHhJQ2s1S0VNZExVRW9xPXM5Ni1jIiwiaXNzIjoiaHR0cHM6Ly9zZWN1cmV0b2tlbi5nb29nbGUuY29tL2NhcmJvbi10cmFjay1zeXN0ZW0iLCJhdWQiOiJjYXJib24tdHJhY2stc3lzdGVtIiwiYXV0aF90aW1lIjoxNjk4NTMwMzE3LCJ1c2VyX2lkIjoiUkZSbmdJVm1Bd1BHY0pxVFVPalZOeFB4SzVzMSIsInN1YiI6IlJGUm5nSVZtQXdQR2NKcVRVT2pWTnhQeEs1czEiLCJpYXQiOjE2OTg1MzAzMTcsImV4cCI6MTY5ODUzMzkxNywiZW1haWwiOiJ5YXphbi5hcm1vdXNoMUBnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiZmlyZWJhc2UiOnsiaWRlbnRpdGllcyI6eyJnb29nbGUuY29tIjpbIjExNzEyOTg2MDYwMzg2MDUxODQwOCJdLCJlbWFpbCI6WyJ5YXphbi5hcm1vdXNoMUBnbWFpbC5jb20iXX0sInNpZ25faW5fcHJvdmlkZXIiOiJnb29nbGUuY29tIn19.D586V3FjImF4P46sjEw1VuwgHXY5VTHPPrQAzC1thWqe5rASSYqxPRtn53xCD8_mxAzNjPu5zmGLmuiW0AL3x8hs4KiB8jhGlcx_z32mfDOBqvhlqgJw6HEsQRj7kziPvD1gnTt0I4xVuculKFSY6gYeyoii6_A6fN4frqoR59qzb4iNDXnHaKovleUB9VWmzG1cLcvzSP1nXSvj8tNIR_e52yTPq9tpAf-hkzs_1dTS3a65canzVOW_F6plnX79TZJ5N9Wvm7669cX8v2qUb-e5gBkMnU2i70jjheacaXVuHx_cb-JIK12VpmrsVfJGSD_uwCfODHf140lfdr_okg",
"type": "string"
"method": "POST",
"header": [],
"body": {
"mode": "raw",
"raw": "{\n \"start\": \"2023-01-01T00:00:00Z\",\n \"end\": \"2023-12-01T00:00:00Z\"\n}",
"options": {
"raw": {
"language": "json"
}
]
}
},
"url": {
"raw": "{{LocalBaseURL}}/transportation/get_transportations_entries_for_user_using_data_range",
"host": [
"{{LocalBaseURL}}"
],
"path": [
"transportation",
"get_transportations_entries_for_user_using_data_range"
]
}
},
"response": []
},
{
"name": "Update Transportation",
"request": {
"method": "PATCH",
"header": [],
"body": {
"mode": "raw",
"raw": "{\n \"transportation\": {\n \"_id\": \"6552c6a8d6755e16ea2a73bd\",\n \"bus\": 0,\n \"carbon_emissions\": 0.0,\n \"electric_car\": 3000,\n \"gasoline_car\": 200,\n \"date\": {\n \"$date\": \"2023-11-12T00:00:00Z\"\n },\n \"motorbike\": 50,\n \"plane\": 0,\n \"train\": 50,\n \"user_id\": \"655151e8875bab2e6811b8b8\"\n }\n}",
"raw": "{\n \"transportation\": {\n \"_id\": \"655d5c7d123217b52115b046\",\n \"bus\": 200,\n \"carbon_emissions\": 0.0,\n \"date\": \"2023-11-19T00:00:00Z\",\n \"electric_car\": 4000,\n \"gasoline_car\": 100,\n \"motorbike\": 0,\n \"train\": 0,\n \"user_id\": \"655151e8875bab2e6811b8b8\"\n }\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{LocalBaseURL}}/transportation/transportation/6552c6a8d6755e16ea2a73bd",
"raw": "{{LocalBaseURL}}/transportation/transportation/655d625a1df1b3b87663ba71",
"host": [
"{{LocalBaseURL}}"
],
"path": [
"transportation",
"transportation",
"6552c6a8d6755e16ea2a73bd"
"655d625a1df1b3b87663ba71"
]
}
},
"response": []
}
],
"event": [
{
"listen": "prerequest",
"script": {
"type": "text/javascript",
"exec": [
""
]
}
},
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
""
]
}
}
]
},
{
Expand All @@ -267,6 +293,16 @@
"response": []
}
],
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjBiYmQyOTllODU2MmU3MmYyZThkN2YwMTliYTdiZjAxMWFlZjU1Y2EiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL3NlY3VyZXRva2VuLmdvb2dsZS5jb20vY2FyYm9uLXRyYWNrLXN5c3RlbSIsImF1ZCI6ImNhcmJvbi10cmFjay1zeXN0ZW0iLCJhdXRoX3RpbWUiOjE3MDA4NDg5NjgsInVzZXJfaWQiOiJ3UFVEaEFiM0Q5ZHpoeDJXa1RBZlBLbnhGSG0xIiwic3ViIjoid1BVRGhBYjNEOWR6aHgyV2tUQWZQS254RkhtMSIsImlhdCI6MTcwMDg0ODk2OCwiZXhwIjoxNzAwODUyNTY4LCJlbWFpbCI6InlhemFuQGdtYWlsLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwiZmlyZWJhc2UiOnsiaWRlbnRpdGllcyI6eyJlbWFpbCI6WyJ5YXphbkBnbWFpbC5jb20iXX0sInNpZ25faW5fcHJvdmlkZXIiOiJwYXNzd29yZCJ9fQ.E1XaTAt-BQ6ub7AdOKV_BR8z533NJA-G9DhXI26rffCtZXj55SPpUSYd71t_jVZ2Q8RSZyrKdOkkbW9pwMKw0zUKRCWLpwS5bbWFUBvcX4qhmGiAO6-ZkHYrn9cJiHr6cToT3baPLCzIYuIFzuABjC4w3LZL4C_UQlWhfF2Qois_Qc7-XdNyNJ7e9n0bSlAlM8rOtbkIy0o4T1_9n1rVwM6hiH2ePGWTOjmjcGCSqichttqbYLIhB5NOTrhYXTuTtJtpV_wr2tdi2lDCFoMXGj8DaLVsq4URHJVf_U7JvWKUg50_8wlIZs9c6Px2ypSGIXEYEwUrjtOsIjRlPdPJDA",
"type": "string"
}
]
},
"event": [
{
"listen": "prerequest",
Expand Down
Loading

0 comments on commit a1c1eb6

Please sign in to comment.