Skip to content

Commit

Permalink
Merge branch 'feature/67/recommendations' of https://github.com/utmgd…
Browse files Browse the repository at this point in the history
…sc/CarbonTrack into feature/67/recommendations
  • Loading branch information
IshavSohal committed Dec 16, 2023
2 parents 1cdfad1 + d07a6b6 commit c62e3ac
Show file tree
Hide file tree
Showing 27 changed files with 1,503 additions and 346 deletions.
30 changes: 23 additions & 7 deletions backend/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,25 @@ class User(DB_MODEL):
household: int
fuel_efficiency: float

def __init__(self, oid: ObjectId, full_name: str, email: str, badges: list[str], friends: list[str], monthly_score:int,
yearly_score:int, overall_score:int, province:str, household:int, fuel_efficiency: float) -> None:
def __init__(
self,
oid: ObjectId,
full_name: str,
email: str,
uid: str,
badges: list[str],
friends: list[str],
monthly_score:int,
yearly_score:int,
overall_score:int,
province: str,
household: int,
fuel_efficiency: float,
) -> None:
super().__init__(oid)
self.full_name = str(full_name)
self.email = str(email)
self.uid = uid
self.badges = badges
self.friends = friends
self.monthly_score = monthly_score
Expand All @@ -37,9 +51,10 @@ def __init__(self, oid: ObjectId, full_name: str, email: str, badges: list[str],

def to_json(self) -> json:
return {
'_id': self.oid,
'full_name': self.full_name,
'email': self.email,
"_id": self.oid,
"full_name": self.full_name,
"email": self.email,
"uid": self.uid,
'badges': self.badges,
'friends': self.friends,
'monthly_score': self.monthly_score,
Expand All @@ -56,15 +71,16 @@ def from_json(doc: json) -> User:
oid=ObjectId(doc["_id"]),
full_name=doc["full_name"],
email=doc["email"],
uid=doc["uid"],
badges=doc["badges"],
friends=doc["friends"],
monthly_score=doc["monthly_score"],
yearly_score=doc["yearly_score"],
overall_score=doc["overall_score"],
province=doc["province"],
household=doc["household"],
fuel_efficiency=doc["fuel_efficiency"]
fuel_efficiency=doc["fuel_efficiency"],
)

def __repr__(self) -> str:
return f'User ID: {self.oid.__str__()}'
return f"User ID: {self.oid.__str__()}"
15 changes: 11 additions & 4 deletions backend/routes/carbon_auth.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
from flask_httpauth import HTTPTokenAuth
from utils.FirebaseAPI import FirebaseAPI
from flask import g

auth = HTTPTokenAuth(scheme='Bearer')
auth = HTTPTokenAuth(scheme="Bearer")


@auth.verify_token
def verify_token(token: str) -> bool:
d = FirebaseAPI.verify_google_token(token)
print(f"USER AUTHENTICATED: {bool(d)}")
return bool(d)
user_info = FirebaseAPI.verify_google_token(token)

print(f"USER AUTHENTICATED: {bool(user_info)}")

if user_info:
g.current_user = user_info # Setting the current user in Flask's global object
return True
else:
return False


@auth.error_handler
Expand Down
159 changes: 142 additions & 17 deletions backend/routes/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,22 @@
from mongodb_api.carbon_track_db import CarbonTrackDB
from routes import carbon_auth
from utils.carbon_track_errors import CarbonTrackError
from pymongo.collection import ReturnDocument
from flask import g

users = Blueprint('/users', __name__)
users = Blueprint("/users", __name__)

@users.route("/user/<user_id>", methods=['GET'])
@users.route("/user/<user_id>", methods=["GET"])
@carbon_auth.auth.login_required
def get_user(user_id: str) -> Response:
try:
query = {"_id": ObjectId(user_id)}
item = CarbonTrackDB.users_coll.find_one(query)
item = User.from_json(item).to_json()
return jsonify({'user': item})
return jsonify({"user": item})
except CarbonTrackError as e:
abort(code=400, description=f"{e}")


@users.route("/get_top_users", methods=['POST'])
@carbon_auth.auth.login_required
def get_top_users() -> Response:
Expand Down Expand Up @@ -87,16 +88,48 @@ def get_user_by_email(user_email: str) -> Response:
query = {"email": user_email}
item = CarbonTrackDB.users_coll.find_one(query)
item = User.from_json(item).to_json()
return jsonify({'user': item})
return jsonify({"user": item})
except CarbonTrackError as e:
abort(code=400, description=f"{e}")


@users.route("/user", methods=['PUT'])
@users.route("/current", methods=["GET"])
@carbon_auth.auth.login_required
def get_current_user() -> Response:
try:
current_user = g.current_user

print(current_user)

# Construct the query to find the user in MongoDB
query = {"uid": current_user["uid"]}

# Fetch user data from MongoDB
mongo_user = CarbonTrackDB.users_coll.find_one(query)

# Check if user exists in MongoDB and update if necessary
if mongo_user is not None:
# Check if the email in Firebase and MongoDB are different
if mongo_user.get("email") != current_user["email"]:
update = {"$set": {"email": current_user["email"]}}
mongo_user = CarbonTrackDB.users_coll.find_one_and_update(
query, update, return_document=ReturnDocument.AFTER
)
else:
# Handle case where user is not found in MongoDB
abort(code=404, description="User not found in database")

user_data = User.from_json(mongo_user).to_json()
return jsonify({"user": user_data})
except CarbonTrackError as e:
abort(code=400, description=str(e))


@users.route("/user", methods=["PUT"])
@carbon_auth.auth.login_required
def create_user() -> Response:
try:
res: dict = request.get_json()['user']
res: dict = request.get_json()["user"]
user = User.from_json(res)
user.email = user.email.lower()

Expand All @@ -105,23 +138,27 @@ def create_user() -> Response:
if item is None:
user = user.to_json()
inserted_id = CarbonTrackDB.users_coll.insert_one(user).inserted_id
user = User.from_json(CarbonTrackDB.users_coll.find_one({"_id": inserted_id})).to_json()
return jsonify({'user': user})
user = User.from_json(
CarbonTrackDB.users_coll.find_one({"_id": inserted_id})
).to_json()
return jsonify({"user": user})
else:
return jsonify({'error': "User Already Exits With Same Email, Please Log In"})
return jsonify(
{"error": "User Already Exits With Same Email, Please Log In"}
)
except CarbonTrackError as e:
abort(code=400, description=f"{e}")


@users.route("/user/<user_id>", methods=['DELETE'])
@users.route("/user/<user_id>", methods=["DELETE"])
@carbon_auth.auth.login_required
def delete_user(user_id: str) -> Response:
try:
query = {"_id": ObjectId(user_id)}
item = CarbonTrackDB.users_coll.find_one(query)
item = User.from_json(item).to_json()
CarbonTrackDB.users_coll.delete_one(query)
return jsonify({'deleted user': item})
return jsonify({"deleted user": item})
except CarbonTrackError as e:
abort(code=400, description=f"{e}")

Expand All @@ -131,12 +168,100 @@ def delete_user(user_id: str) -> Response:
def update_user(user_id: str) -> Response:
try:
query = {"_id": ObjectId(user_id)}
user = User.from_json(request.get_json()['user']).to_json()
del user['_id']
del user['email']
CarbonTrackDB.users_coll.update_one(query, {'$set': user})
user = User.from_json(request.get_json()["user"]).to_json()
del user["_id"]
del user["email"]
CarbonTrackDB.users_coll.update_one(query, {"$set": user})
item = CarbonTrackDB.users_coll.find_one(query)
item = User.from_json(item).to_json()
return jsonify({"user": item})
except CarbonTrackError as e:
abort(code=400, description=f"{e}")


@users.route("/user/update_email/<user_id>", methods=["PATCH"])
@carbon_auth.auth.login_required
def update_user_email(uid: str) -> Response:
try:
query = {"uid": uid}
new_email = request.get_json().get("email", "")

current_user = carbon_auth.auth.current_user()
print(current_user)

CarbonTrackDB.users_coll.update_one(query, {"$set": {"email": new_email}})

item = CarbonTrackDB.users_coll.find_one(query)

item = User.from_json(item).to_json()

return jsonify({"user": item})
except CarbonTrackError as e:
abort(code=400, description=f"{e}")

@users.route("/user/update_name/<user_id>", methods=["PATCH"])
@carbon_auth.auth.login_required
def update_user_name(user_id: str) -> Response:
try:
new_name = request.get_json().get("newName", "")

query = {"uid": user_id}

current_user = carbon_auth.auth.current_user()
print(current_user)

CarbonTrackDB.users_coll.update_one(query, {"$set": {"full_name": new_name}})

item = CarbonTrackDB.users_coll.find_one(query)

item = User.from_json(item).to_json()
return jsonify({'user': item})

return jsonify({"user": item}), 200
except CarbonTrackError as e:
abort(code=400, description=f"{e}")


@users.route("/user/update_province/<user_id>", methods=["PATCH"])
def update_user_province(user_id: str) -> Response:
try:
print("Updating province...")
new_province = request.get_json().get("newProvince", "")
print("Updating province...")
query = {"uid": user_id}

updated_user = CarbonTrackDB.users_coll.find_one_and_update(
query,
{"$set": {"province": new_province}},
return_document=ReturnDocument.AFTER
)

updated_user = User.from_json(updated_user).to_json()

return jsonify({"user": updated_user}), 200
except CarbonTrackError as e:
abort(code=400, description=f"{e}")

@users.route("/user/update_occupancy/<user_id>", methods=["PATCH"])
def update_user_occupancy(user_id: str) -> Response:
try:
print("Updating occupancy...")
print(request.get_json())
new_occupancy = request.get_json().get("newOccupancy", 0)
query = {"uid": user_id}

current_user = carbon_auth.auth.current_user()
print(current_user)

print(f"Updating occupancy for user {user_id} to {new_occupancy}")

CarbonTrackDB.users_coll.update_one(query, {"$set": {"household": new_occupancy}})

item = CarbonTrackDB.users_coll.find_one(query)

item = User.from_json(item).to_json()

print(f"User updated: {item}")

return jsonify({"user": item}), 200
except CarbonTrackError as e:
abort(code=400, description=f"{e}")
8 changes: 8 additions & 0 deletions backend/utils/FirebaseAPI.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,11 @@ def get_user(id_token: str) -> Optional[User]:
item = CarbonTrackDB.users_coll.find_one(query)
item = User.from_json(item)
return item
@staticmethod
def refresh_token(user_id):
try:
user = auth.get_user(user_id)
new_id_token = user.refresh_id_tokens()
return new_id_token
except auth.AuthError as e:
raise e
8 changes: 8 additions & 0 deletions frontend/app.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
{
"expo": {
"plugins": [
[
"expo-image-picker",
{
"photosPermission": "The app accesses your photos to let you share them with your friends."
}
]
],
"name": "CarbonTrack",
"slug": "CarbonTrack",
"version": "1.0.0",
Expand Down
13 changes: 8 additions & 5 deletions frontend/assets/colorConstants.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
const Colors = {
LIGHTFGREEN: '#d8edc2',
DARKGREEN: '#012b26',
DARKTRANS: '#07332f',
LIGHTFGREEN: '#E0EEC6',
DARKGREEN: '#10302b',
DARKGREEN2: '#224A3E',
DARKGREEN3: '#2E5C4E',
LIGHTGREENBUTTON: '#a5ba8f',
LIGHTGREENBACK: '#C7E0A6',
WHITE: '#ffffff',
BLACK: '#000000',
DARKLIMEGREEN: '#4B8552',
GREY: '#cccccc',
GREY: '#ccc',
FILLGREEN: '#7CA982',
ERROR: 'red',
TRANSGREEN: '#366959',
BLACKTRANS: '#000000aa',
BLUE: 'blue',
TEAL: '#6bcfca',
TRANSLIGHTGREEN: '#c6dbb2',
TRANSLIGHTGREEN2: '#b3c99d',
TRANSGREENBACK: '#07332b',
DARKDARKGREEN: '#031c19',
GREYGREEN: '#B4C792',
TEAL: '#6bcfca'
};

export default Colors;
4 changes: 3 additions & 1 deletion frontend/assets/foodQuestions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ const foodSlidersData: SliderData[] = [
{ id: 1, label: 'Beef', minValue: 0, maxValue: 8, initialValue: 0 },
{ id: 2, label: 'Lamb', minValue: 0, maxValue: 8, initialValue: 0 },
{ id: 3, label: 'Pork', minValue: 0, maxValue: 8, initialValue: 0 },
{ id: 4, label: 'Chicken/Fish', minValue: 0, maxValue: 8, initialValue: 0 },
{ id: 4, label: 'Chicken', minValue: 0, maxValue: 8, initialValue: 0 },
{ id: 5, label: 'Fish', minValue: 0, maxValue: 8, initialValue: 0 },
{ id: 6, label: 'Cheese', minValue: 0, maxValue: 8, initialValue: 0 },
];

export default foodSlidersData;
9 changes: 6 additions & 3 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
"@react-native-async-storage/async-storage": "^1.18.2",
"@react-native-community/masked-view": "^0.1.11",
"@react-native-community/slider": "^4.4.2",
"@react-native-firebase/auth": "^18.6.0",
"@react-native-firebase/app": "^18.7.1",
"@react-native-firebase/auth": "^18.7.1",
"@react-native-firebase/firestore": "^18.6.0",
"@react-native-picker/picker": "2.4.10",
"@react-native-firebase/storage": "^18.7.1",
"@react-native-picker/picker": "^2.5.1",
"@react-navigation/bottom-tabs": "^6.5.11",
"@react-navigation/native": "^6.1.9",
"@react-navigation/native-stack": "^6.9.15",
Expand All @@ -27,8 +29,9 @@
"events": "^3.3.0",
"expo": "~49.0.12",
"expo-font": "~11.4.0",
"expo-image-picker": "~14.3.2",
"expo-status-bar": "~1.6.0",
"firebase": "^10.5.2",
"firebase": "^10.7.1",
"formik": "^2.4.5",
"mongodb": "^6.3.0",
"react": "^18.2.0",
Expand Down
Loading

0 comments on commit c62e3ac

Please sign in to comment.