2424from src .models .workout import Workout as WorkoutModel
2525from src .models .report import Report as ReportModel
2626from src .models .hourly_average_capacity import HourlyAverageCapacity as HourlyAverageCapacityModel
27+ from src .utils .constants import SHEET_KEY , SHEET_REPORTS , SERVICE_ACCOUNT_PATH
2728from src .database import db_session
2829import requests
29- import json
30- import os
3130from firebase_admin import messaging
3231import logging
32+ import gspread
33+
34+
35+ # Configure client and sheet
36+ gc = gspread .service_account (filename = SERVICE_ACCOUNT_PATH )
37+ sh = gc .open_by_key (SHEET_KEY )
3338
3439
3540def resolve_enum_value (entry ):
3641 """Return the raw value for Enum objects while leaving plain strings untouched."""
3742 return getattr (entry , "value" , entry )
3843
44+
3945# MARK: - Gym
4046
4147
@@ -239,6 +245,7 @@ class UserInput(graphene.InputObjectType):
239245
240246# MARK: - Friendship
241247
248+
242249class Friendship (SQLAlchemyObjectType ):
243250 class Meta :
244251 model = FriendshipModel
@@ -254,6 +261,7 @@ def resolve_friend(self, info):
254261 query = User .get_query (info ).filter (UserModel .id == self .friend_id ).first ()
255262 return query
256263
264+
257265# MARK: - Giveaway
258266
259267
@@ -327,19 +335,12 @@ class Query(graphene.ObjectType):
327335 HourlyAverageCapacity , facility_id = graphene .Int (), description = "Get all facility hourly average capacities."
328336 )
329337 get_user_friends = graphene .List (
330- User ,
331- user_id = graphene .Int (required = True ),
332- description = "Get all friends for a user."
338+ User , user_id = graphene .Int (required = True ), description = "Get all friends for a user."
333339 )
334340 get_capacity_reminder_by_id = graphene .Field (
335- CapacityReminder ,
336- id = graphene .Int (required = True ),
337- description = "Get a specific capacity reminder by its ID."
338- )
339- get_all_capacity_reminders = graphene .List (
340- CapacityReminder ,
341- description = "Get all capacity reminders."
341+ CapacityReminder , id = graphene .Int (required = True ), description = "Get a specific capacity reminder by its ID."
342342 )
343+ get_all_capacity_reminders = graphene .List (CapacityReminder , description = "Get all capacity reminders." )
343344
344345 def resolve_get_all_gyms (self , info ):
345346 query = Gym .get_query (info )
@@ -464,14 +465,18 @@ def resolve_get_user_friends(self, info, user_id):
464465 raise GraphQLError ("User with the given ID does not exist." )
465466
466467 # Direct friendships where user is the initiator
467- direct_friendships = Friendship .get_query (info ).filter (
468- (FriendshipModel .user_id == user_id ) & (FriendshipModel .is_accepted == True )
469- ).all ()
468+ direct_friendships = (
469+ Friendship .get_query (info )
470+ .filter ((FriendshipModel .user_id == user_id ) & (FriendshipModel .is_accepted == True ))
471+ .all ()
472+ )
470473
471474 # Reverse friendships where user is the recipient
472- reverse_friendships = Friendship .get_query (info ).filter (
473- (FriendshipModel .friend_id == user_id ) & (FriendshipModel .is_accepted == True )
474- ).all ()
475+ reverse_friendships = (
476+ Friendship .get_query (info )
477+ .filter ((FriendshipModel .friend_id == user_id ) & (FriendshipModel .is_accepted == True ))
478+ .all ()
479+ )
475480
476481 friend_ids = set ()
477482 for friendship in direct_friendships :
@@ -482,7 +487,7 @@ def resolve_get_user_friends(self, info, user_id):
482487
483488 # Query for all friends at once
484489 return User .get_query (info ).filter (UserModel .id .in_ (friend_ids )).all ()
485-
490+
486491 @jwt_required ()
487492 def resolve_get_capacity_reminder_by_id (self , info , id ):
488493 reminder = CapacityReminder .get_query (info ).filter (CapacityReminderModel .id == id ).first ()
@@ -491,7 +496,7 @@ def resolve_get_capacity_reminder_by_id(self, info, id):
491496 raise GraphQLError ("Capacity reminder with the given ID does not exist." )
492497
493498 return reminder
494-
499+
495500 @jwt_required ()
496501 def resolve_get_all_capacity_reminders (self , info ):
497502 query = CapacityReminder .get_query (info )
@@ -687,6 +692,7 @@ def mutate(self, info, name):
687692 db_session .commit ()
688693 return giveaway
689694
695+
690696class AddFriend (graphene .Mutation ):
691697 class Arguments :
692698 user_net_id = graphene .String (required = True , description = "The Net ID of the user." )
@@ -710,6 +716,7 @@ def mutate(self, info, user_net_id, friend_net_id):
710716 db_session .commit ()
711717 return user
712718
719+
713720class RemoveFriend (graphene .Mutation ):
714721 class Arguments :
715722 user_net_id = graphene .String (required = True , description = "The Net ID of the user." )
@@ -733,6 +740,7 @@ def mutate(self, info, user_net_id, friend_net_id):
733740 db_session .commit ()
734741 return user
735742
743+
736744class SetWorkoutGoals (graphene .Mutation ):
737745 class Arguments :
738746 user_id = graphene .Int (required = True , description = "The ID of the user." )
@@ -816,9 +824,39 @@ def mutate(self, info, description, issue, created_at, gym_id):
816824 report = ReportModel (description = description , issue = issue , created_at = created_at , gym_id = gym_id )
817825 db_session .add (report )
818826 db_session .commit ()
827+
828+ try :
829+ sh .worksheet (SHEET_REPORTS ).append_row ([report .id , issue , gym .name , description , created_at .isoformat ()])
830+ except Exception as e :
831+ print (f"Error logging report to sheet: { e } " )
832+
819833 return CreateReport (report = report )
820834
821835
836+ class DeleteReport (graphene .Mutation ):
837+ class Arguments :
838+ report_id = graphene .Int (required = True )
839+
840+ Output = Report
841+
842+ def mutate (self , info , report_id ):
843+ # Check if report exists
844+ report = Report .get_query (info ).filter (ReportModel .id == report_id ).first ()
845+ if not report :
846+ raise GraphQLError ("Report with given ID does not exist." )
847+
848+ try :
849+ worksheet = sh .worksheet (SHEET_REPORTS )
850+ cell = worksheet .find (str (report_id ), in_column = 1 )
851+ worksheet .delete_rows (cell .row )
852+ except Exception as e :
853+ print (f"Error deleting report from sheet: { e } " )
854+
855+ db_session .delete (report )
856+ db_session .commit ()
857+ return report
858+
859+
822860class DeleteUserById (graphene .Mutation ):
823861 class Arguments :
824862 user_id = graphene .Int (required = True )
@@ -927,11 +965,7 @@ def mutate(self, info, reminder_id, new_gyms, days_of_week, new_capacity_thresho
927965 for topic in topics :
928966 try :
929967 response = messaging .unsubscribe_from_topic (reminder .fcm_token , topic )
930- logging .info (
931- "Unsubscribe %s from %s" ,
932- reminder .fcm_token [:12 ],
933- topic ,
934- )
968+ logging .info ("Unsubscribe %s from %s" , reminder .fcm_token [:12 ], topic )
935969 for error in response .errors :
936970 logging .warning (
937971 "Error unsubscribing %s from %s -> reason: %s" , reminder .fcm_token [:12 ], topic , error .reason
@@ -947,11 +981,7 @@ def mutate(self, info, reminder_id, new_gyms, days_of_week, new_capacity_thresho
947981 for topic in topics :
948982 try :
949983 response = messaging .subscribe_to_topic (reminder .fcm_token , topic )
950- logging .info (
951- "Resubscribing %s to %s" ,
952- reminder .fcm_token [:12 ],
953- topic ,
954- )
984+ logging .info ("Resubscribing %s to %s" , reminder .fcm_token [:12 ], topic )
955985 if response .success_count == 0 :
956986 raise Exception (response .errors [0 ].reason )
957987 except Exception as error :
@@ -985,13 +1015,9 @@ def mutate(self, info, reminder_id):
9851015 for topic in topics :
9861016 try :
9871017 response = messaging .unsubscribe_from_topic (reminder .fcm_token , topic )
988- logging .info (
989- "Unsubscribe %s from %s" ,
990- reminder .fcm_token [:12 ],
991- topic ,
992- )
1018+ logging .info ("Unsubscribe %s from %s" , reminder .fcm_token [:12 ], topic )
9931019 if response .success_count == 0 :
994- raise Exception (response .errors [0 ].reason )
1020+ raise Exception (response .errors [0 ].reason )
9951021 except Exception as error :
9961022 raise GraphQLError (f"Error unsubscribing from topic { topic } : { error } " )
9971023
@@ -1000,6 +1026,7 @@ def mutate(self, info, reminder_id):
10001026
10011027 return reminder
10021028
1029+
10031030class AddFriend (graphene .Mutation ):
10041031 class Arguments :
10051032 user_id = graphene .Int (required = True )
@@ -1019,10 +1046,14 @@ def mutate(self, info, user_id, friend_id):
10191046 raise GraphQLError ("Friend with given ID does not exist." )
10201047
10211048 # Check if friendship already exists
1022- existing = Friendship .get_query (info ).filter (
1023- ((FriendshipModel .user_id == user_id ) & (FriendshipModel .friend_id == friend_id )) |
1024- ((FriendshipModel .user_id == friend_id ) & (FriendshipModel .friend_id == user_id ))
1025- ).first ()
1049+ existing = (
1050+ Friendship .get_query (info )
1051+ .filter (
1052+ ((FriendshipModel .user_id == user_id ) & (FriendshipModel .friend_id == friend_id ))
1053+ | ((FriendshipModel .user_id == friend_id ) & (FriendshipModel .friend_id == user_id ))
1054+ )
1055+ .first ()
1056+ )
10261057
10271058 if existing :
10281059 raise GraphQLError ("Friendship already exists." )
@@ -1034,6 +1065,7 @@ def mutate(self, info, user_id, friend_id):
10341065
10351066 return friendship
10361067
1068+
10371069class AcceptFriendRequest (graphene .Mutation ):
10381070 class Arguments :
10391071 friendship_id = graphene .Int (required = True )
@@ -1058,6 +1090,7 @@ def mutate(self, info, friendship_id):
10581090
10591091 return friendship
10601092
1093+
10611094class RemoveFriend (graphene .Mutation ):
10621095 class Arguments :
10631096 user_id = graphene .Int (required = True )
@@ -1068,10 +1101,14 @@ class Arguments:
10681101 @jwt_required ()
10691102 def mutate (self , info , user_id , friend_id ):
10701103 # Find the friendship
1071- friendship = Friendship .get_query (info ).filter (
1072- ((FriendshipModel .user_id == user_id ) & (FriendshipModel .friend_id == friend_id )) |
1073- ((FriendshipModel .user_id == friend_id ) & (FriendshipModel .friend_id == user_id ))
1074- ).first ()
1104+ friendship = (
1105+ Friendship .get_query (info )
1106+ .filter (
1107+ ((FriendshipModel .user_id == user_id ) & (FriendshipModel .friend_id == friend_id ))
1108+ | ((FriendshipModel .user_id == friend_id ) & (FriendshipModel .friend_id == user_id ))
1109+ )
1110+ .first ()
1111+ )
10751112
10761113 if not friendship :
10771114 raise GraphQLError ("Friendship not found." )
@@ -1082,6 +1119,7 @@ def mutate(self, info, user_id, friend_id):
10821119
10831120 return RemoveFriend (success = True )
10841121
1122+
10851123class GetPendingFriendRequests (graphene .Mutation ):
10861124 class Arguments :
10871125 user_id = graphene .Int (required = True )
@@ -1096,10 +1134,11 @@ def mutate(self, info, user_id):
10961134 raise GraphQLError ("User with given ID does not exist." )
10971135
10981136 # Get pending friend requests (where this user is the friend)
1099- pending = Friendship .get_query (info ).filter (
1100- (FriendshipModel .friend_id == user_id ) &
1101- (FriendshipModel .is_accepted == False )
1102- ).all ()
1137+ pending = (
1138+ Friendship .get_query (info )
1139+ .filter ((FriendshipModel .friend_id == user_id ) & (FriendshipModel .is_accepted == False ))
1140+ .all ()
1141+ )
11031142
11041143 return GetPendingFriendRequests (pending_requests = pending )
11051144
@@ -1115,6 +1154,7 @@ class Mutation(graphene.ObjectType):
11151154 logout_user = LogoutUser .Field (description = "Logs out a user." )
11161155 refresh_access_token = RefreshAccessToken .Field (description = "Refreshes the access token." )
11171156 create_report = CreateReport .Field (description = "Creates a new report." )
1157+ delete_report = DeleteReport .Field (description = "Deletes a report by ID." )
11181158 delete_user = DeleteUserById .Field (description = "Deletes a user by ID." )
11191159 add_friend = AddFriend .Field (description = "Adds a friend to a user." )
11201160 remove_friend = RemoveFriend .Field (description = "Removes a friend from a user." )
@@ -1125,7 +1165,8 @@ class Mutation(graphene.ObjectType):
11251165 accept_friend_request = AcceptFriendRequest .Field (description = "Accept a friend request." )
11261166 remove_friend = RemoveFriend .Field (description = "Remove a friendship." )
11271167 get_pending_friend_requests = GetPendingFriendRequests .Field (
1128- description = "Get all pending friend requests for a user." )
1168+ description = "Get all pending friend requests for a user."
1169+ )
11291170
11301171
11311172schema = graphene .Schema (query = Query , mutation = Mutation )
0 commit comments