Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 90 additions & 49 deletions src/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,24 @@
from src.models.workout import Workout as WorkoutModel
from src.models.report import Report as ReportModel
from src.models.hourly_average_capacity import HourlyAverageCapacity as HourlyAverageCapacityModel
from src.utils.constants import SHEET_KEY, SHEET_REPORTS, SERVICE_ACCOUNT_PATH
from src.database import db_session
import requests
import json
import os
from firebase_admin import messaging
import logging
import gspread


# Configure client and sheet
gc = gspread.service_account(filename=SERVICE_ACCOUNT_PATH)
sh = gc.open_by_key(SHEET_KEY)


def resolve_enum_value(entry):
"""Return the raw value for Enum objects while leaving plain strings untouched."""
return getattr(entry, "value", entry)


# MARK: - Gym


Expand Down Expand Up @@ -239,6 +245,7 @@ class UserInput(graphene.InputObjectType):

# MARK: - Friendship


class Friendship(SQLAlchemyObjectType):
class Meta:
model = FriendshipModel
Expand All @@ -254,6 +261,7 @@ def resolve_friend(self, info):
query = User.get_query(info).filter(UserModel.id == self.friend_id).first()
return query


# MARK: - Giveaway


Expand Down Expand Up @@ -327,19 +335,12 @@ class Query(graphene.ObjectType):
HourlyAverageCapacity, facility_id=graphene.Int(), description="Get all facility hourly average capacities."
)
get_user_friends = graphene.List(
User,
user_id=graphene.Int(required=True),
description="Get all friends for a user."
User, user_id=graphene.Int(required=True), description="Get all friends for a user."
)
get_capacity_reminder_by_id = graphene.Field(
CapacityReminder,
id=graphene.Int(required=True),
description="Get a specific capacity reminder by its ID."
)
get_all_capacity_reminders = graphene.List(
CapacityReminder,
description="Get all capacity reminders."
CapacityReminder, id=graphene.Int(required=True), description="Get a specific capacity reminder by its ID."
)
get_all_capacity_reminders = graphene.List(CapacityReminder, description="Get all capacity reminders.")

def resolve_get_all_gyms(self, info):
query = Gym.get_query(info)
Expand Down Expand Up @@ -464,14 +465,18 @@ def resolve_get_user_friends(self, info, user_id):
raise GraphQLError("User with the given ID does not exist.")

# Direct friendships where user is the initiator
direct_friendships = Friendship.get_query(info).filter(
(FriendshipModel.user_id == user_id) & (FriendshipModel.is_accepted == True)
).all()
direct_friendships = (
Friendship.get_query(info)
.filter((FriendshipModel.user_id == user_id) & (FriendshipModel.is_accepted == True))
.all()
)

# Reverse friendships where user is the recipient
reverse_friendships = Friendship.get_query(info).filter(
(FriendshipModel.friend_id == user_id) & (FriendshipModel.is_accepted == True)
).all()
reverse_friendships = (
Friendship.get_query(info)
.filter((FriendshipModel.friend_id == user_id) & (FriendshipModel.is_accepted == True))
.all()
)

friend_ids = set()
for friendship in direct_friendships:
Expand All @@ -482,7 +487,7 @@ def resolve_get_user_friends(self, info, user_id):

# Query for all friends at once
return User.get_query(info).filter(UserModel.id.in_(friend_ids)).all()

@jwt_required()
def resolve_get_capacity_reminder_by_id(self, info, id):
reminder = CapacityReminder.get_query(info).filter(CapacityReminderModel.id == id).first()
Expand All @@ -491,7 +496,7 @@ def resolve_get_capacity_reminder_by_id(self, info, id):
raise GraphQLError("Capacity reminder with the given ID does not exist.")

return reminder

@jwt_required()
def resolve_get_all_capacity_reminders(self, info):
query = CapacityReminder.get_query(info)
Expand Down Expand Up @@ -687,6 +692,7 @@ def mutate(self, info, name):
db_session.commit()
return giveaway


class AddFriend(graphene.Mutation):
class Arguments:
user_net_id = graphene.String(required=True, description="The Net ID of the user.")
Expand All @@ -710,6 +716,7 @@ def mutate(self, info, user_net_id, friend_net_id):
db_session.commit()
return user


class RemoveFriend(graphene.Mutation):
class Arguments:
user_net_id = graphene.String(required=True, description="The Net ID of the user.")
Expand All @@ -733,6 +740,7 @@ def mutate(self, info, user_net_id, friend_net_id):
db_session.commit()
return user


class SetWorkoutGoals(graphene.Mutation):
class Arguments:
user_id = graphene.Int(required=True, description="The ID of the user.")
Expand Down Expand Up @@ -816,9 +824,39 @@ def mutate(self, info, description, issue, created_at, gym_id):
report = ReportModel(description=description, issue=issue, created_at=created_at, gym_id=gym_id)
db_session.add(report)
db_session.commit()

try:
sh.worksheet(SHEET_REPORTS).append_row([report.id, issue, gym.name, description, created_at.isoformat()])
except Exception as e:
print(f"Error logging report to sheet: {e}")

return CreateReport(report=report)


class DeleteReport(graphene.Mutation):
class Arguments:
report_id = graphene.Int(required=True)

Output = Report

def mutate(self, info, report_id):
# Check if report exists
report = Report.get_query(info).filter(ReportModel.id == report_id).first()
if not report:
raise GraphQLError("Report with given ID does not exist.")

try:
worksheet = sh.worksheet(SHEET_REPORTS)
cell = worksheet.find(str(report_id), in_column=1)
worksheet.delete_rows(cell.row)
except Exception as e:
print(f"Error deleting report from sheet: {e}")

db_session.delete(report)
db_session.commit()
return report


class DeleteUserById(graphene.Mutation):
class Arguments:
user_id = graphene.Int(required=True)
Expand Down Expand Up @@ -927,11 +965,7 @@ def mutate(self, info, reminder_id, new_gyms, days_of_week, new_capacity_thresho
for topic in topics:
try:
response = messaging.unsubscribe_from_topic(reminder.fcm_token, topic)
logging.info(
"Unsubscribe %s from %s",
reminder.fcm_token[:12],
topic,
)
logging.info("Unsubscribe %s from %s", reminder.fcm_token[:12], topic)
for error in response.errors:
logging.warning(
"Error unsubscribing %s from %s -> reason: %s", reminder.fcm_token[:12], topic, error.reason
Expand All @@ -947,11 +981,7 @@ def mutate(self, info, reminder_id, new_gyms, days_of_week, new_capacity_thresho
for topic in topics:
try:
response = messaging.subscribe_to_topic(reminder.fcm_token, topic)
logging.info(
"Resubscribing %s to %s",
reminder.fcm_token[:12],
topic,
)
logging.info("Resubscribing %s to %s", reminder.fcm_token[:12], topic)
if response.success_count == 0:
raise Exception(response.errors[0].reason)
except Exception as error:
Expand Down Expand Up @@ -985,13 +1015,9 @@ def mutate(self, info, reminder_id):
for topic in topics:
try:
response = messaging.unsubscribe_from_topic(reminder.fcm_token, topic)
logging.info(
"Unsubscribe %s from %s",
reminder.fcm_token[:12],
topic,
)
logging.info("Unsubscribe %s from %s", reminder.fcm_token[:12], topic)
if response.success_count == 0:
raise Exception(response.errors[0].reason)
raise Exception(response.errors[0].reason)
except Exception as error:
raise GraphQLError(f"Error unsubscribing from topic {topic}: {error}")

Expand All @@ -1000,6 +1026,7 @@ def mutate(self, info, reminder_id):

return reminder


class AddFriend(graphene.Mutation):
class Arguments:
user_id = graphene.Int(required=True)
Expand All @@ -1019,10 +1046,14 @@ def mutate(self, info, user_id, friend_id):
raise GraphQLError("Friend with given ID does not exist.")

# Check if friendship already exists
existing = Friendship.get_query(info).filter(
((FriendshipModel.user_id == user_id) & (FriendshipModel.friend_id == friend_id)) |
((FriendshipModel.user_id == friend_id) & (FriendshipModel.friend_id == user_id))
).first()
existing = (
Friendship.get_query(info)
.filter(
((FriendshipModel.user_id == user_id) & (FriendshipModel.friend_id == friend_id))
| ((FriendshipModel.user_id == friend_id) & (FriendshipModel.friend_id == user_id))
)
.first()
)

if existing:
raise GraphQLError("Friendship already exists.")
Expand All @@ -1034,6 +1065,7 @@ def mutate(self, info, user_id, friend_id):

return friendship


class AcceptFriendRequest(graphene.Mutation):
class Arguments:
friendship_id = graphene.Int(required=True)
Expand All @@ -1058,6 +1090,7 @@ def mutate(self, info, friendship_id):

return friendship


class RemoveFriend(graphene.Mutation):
class Arguments:
user_id = graphene.Int(required=True)
Expand All @@ -1068,10 +1101,14 @@ class Arguments:
@jwt_required()
def mutate(self, info, user_id, friend_id):
# Find the friendship
friendship = Friendship.get_query(info).filter(
((FriendshipModel.user_id == user_id) & (FriendshipModel.friend_id == friend_id)) |
((FriendshipModel.user_id == friend_id) & (FriendshipModel.friend_id == user_id))
).first()
friendship = (
Friendship.get_query(info)
.filter(
((FriendshipModel.user_id == user_id) & (FriendshipModel.friend_id == friend_id))
| ((FriendshipModel.user_id == friend_id) & (FriendshipModel.friend_id == user_id))
)
.first()
)

if not friendship:
raise GraphQLError("Friendship not found.")
Expand All @@ -1082,6 +1119,7 @@ def mutate(self, info, user_id, friend_id):

return RemoveFriend(success=True)


class GetPendingFriendRequests(graphene.Mutation):
class Arguments:
user_id = graphene.Int(required=True)
Expand All @@ -1096,10 +1134,11 @@ def mutate(self, info, user_id):
raise GraphQLError("User with given ID does not exist.")

# Get pending friend requests (where this user is the friend)
pending = Friendship.get_query(info).filter(
(FriendshipModel.friend_id == user_id) &
(FriendshipModel.is_accepted == False)
).all()
pending = (
Friendship.get_query(info)
.filter((FriendshipModel.friend_id == user_id) & (FriendshipModel.is_accepted == False))
.all()
)

return GetPendingFriendRequests(pending_requests=pending)

Expand All @@ -1115,6 +1154,7 @@ class Mutation(graphene.ObjectType):
logout_user = LogoutUser.Field(description="Logs out a user.")
refresh_access_token = RefreshAccessToken.Field(description="Refreshes the access token.")
create_report = CreateReport.Field(description="Creates a new report.")
delete_report = DeleteReport.Field(description="Deletes a report by ID.")
delete_user = DeleteUserById.Field(description="Deletes a user by ID.")
add_friend = AddFriend.Field(description="Adds a friend to a user.")
remove_friend = RemoveFriend.Field(description="Removes a friend from a user.")
Expand All @@ -1125,7 +1165,8 @@ class Mutation(graphene.ObjectType):
accept_friend_request = AcceptFriendRequest.Field(description="Accept a friend request.")
remove_friend = RemoveFriend.Field(description="Remove a friendship.")
get_pending_friend_requests = GetPendingFriendRequests.Field(
description="Get all pending friend requests for a user.")
description="Get all pending friend requests for a user."
)


schema = graphene.Schema(query=Query, mutation=Mutation)
3 changes: 3 additions & 0 deletions src/utils/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@
# Worksheet name for regular facility hours
SHEET_REG_FACILITY = "[REG] Facility Hours"

# Worksheet name for reports
SHEET_REPORTS = "Reports"

# Worksheet name for special facility hours
SHEET_SP_FACILITY = "[SP] Facility Hours"

Expand Down
Loading