Skip to content

Commit acc684a

Browse files
authored
Merge pull request #197 from cuappdev/user-streaks
Added photo storing for users
2 parents 0b3e413 + db73b5b commit acc684a

4 files changed

Lines changed: 105 additions & 4 deletions

File tree

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""added encoded_image column to user
2+
3+
Revision ID: add99ce06ff5
4+
Revises: 7245f58bb00a
5+
Create Date: 2025-03-12 18:17:26.681109
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
11+
12+
# revision identifiers, used by Alembic.
13+
revision = 'add99ce06ff5'
14+
down_revision = '7245f58bb00a'
15+
branch_labels = None
16+
depends_on = None
17+
18+
19+
def upgrade():
20+
# ### commands auto generated by Alembic - please adjust! ###
21+
op.add_column('users', sa.Column('encoded_image', sa.String(), nullable=True))
22+
# ### end Alembic commands ###
23+
24+
25+
def downgrade():
26+
# ### commands auto generated by Alembic - please adjust! ###
27+
op.drop_column('users', 'encoded_image')
28+
# ### end Alembic commands ###

schema.graphql

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ enum MuscleGroup {
174174

175175
type Mutation {
176176
createGiveaway(name: String!): Giveaway
177-
createUser(email: String!, name: String!, netId: String!): User
177+
createUser(email: String!, encodedImage: String, name: String!, netId: String!): User
178+
editUser(email: String, encodedImage: String, name: String, netId: String!): User
178179
enterGiveaway(giveawayId: Int!, userNetId: String!): GiveawayInstance
179180
setWorkoutGoals(userId: Int!, workoutGoal: [String]!): User
180181
logWorkout(facilityId: Int!, userId: Int!, workoutTime: DateTime!): Workout
@@ -253,6 +254,7 @@ type User {
253254
activeStreak: Int
254255
maxStreak: Int
255256
workoutGoal: [DayOfWeekGraphQLEnum]
257+
encodedImage: String
256258
giveaways: [Giveaway]
257259
}
258260

src/models/user.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class User(Base):
1717
- `active_streak` The number of consecutive weeks the user has met their personal goal.
1818
- `max_streak` The maximum number of consecutive weeks the user has met their personal goal.
1919
- `workout_goal` The max number of weeks the user has met their personal goal.
20+
- `encoded_image` The profile picture URL of the user.
2021
"""
2122

2223
__tablename__ = "users"
@@ -29,3 +30,4 @@ class User(Base):
2930
active_streak = Column(Integer, nullable=True)
3031
max_streak = Column(Integer, nullable=True)
3132
workout_goal = Column(ARRAY(Enum(DayOfWeekEnum)), nullable=True)
33+
encoded_image = Column(String, nullable=True)

src/schema.py

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
from src.models.report import Report as ReportModel
2424
from src.models.hourly_average_capacity import HourlyAverageCapacity as HourlyAverageCapacityModel
2525
from src.database import db_session
26-
26+
import requests
27+
import json
28+
import os
2729

2830
# MARK: - Gym
2931

@@ -427,21 +429,87 @@ class Arguments:
427429
name = graphene.String(required=True)
428430
net_id = graphene.String(required=True)
429431
email = graphene.String(required=True)
432+
encoded_image = graphene.String(required=False)
430433

431434
Output = User
432435

433-
def mutate(self, info, name, net_id, email):
436+
def mutate(self, info, name, net_id, email, encoded_image=None):
434437
# Check if a user with the given NetID already exists
435438
existing_user = db_session.query(UserModel).filter(UserModel.net_id == net_id).first()
439+
final_photo_url = None
436440
if existing_user:
437441
raise GraphQLError("NetID already exists.")
438442

439-
new_user = UserModel(name=name, net_id=net_id, email=email)
443+
if encoded_image:
444+
upload_url = os.getenv("DIGITAL_OCEAN_URL")
445+
payload = {
446+
"bucket": os.getenv("BUCKET_NAME"),
447+
"image": encoded_image # Base64-encoded image string
448+
}
449+
headers = {"Content-Type": "application/json"}
450+
try:
451+
response = requests.post(upload_url, json=payload, headers=headers)
452+
response.raise_for_status()
453+
json_response = response.json()
454+
final_photo_url = json_response.get("data")
455+
if not final_photo_url:
456+
raise GraphQLError("No URL returned from upload service.")
457+
except requests.exceptions.RequestException as e:
458+
print(f"Request failed: {e}")
459+
raise GraphQLError("Failed to upload photo.")
460+
461+
new_user = UserModel(name=name, net_id=net_id, email=email, encoded_image=final_photo_url)
440462
db_session.add(new_user)
441463
db_session.commit()
442464

443465
return new_user
466+
467+
class EditUser(graphene.Mutation):
468+
class Arguments:
469+
name = graphene.String(required=False)
470+
net_id = graphene.String(required=True)
471+
email = graphene.String(required=False)
472+
encoded_image = graphene.String(required=False)
444473

474+
Output = User
475+
476+
def mutate(self, info, net_id, name=None, email=None, encoded_image=None):
477+
existing_user = db_session.query(UserModel).filter(UserModel.net_id == net_id).first()
478+
if not existing_user:
479+
raise GraphQLError("User with given net id does not exist.")
480+
481+
if name is not None:
482+
existing_user.name = name
483+
if email is not None:
484+
existing_user.email = email
485+
if encoded_image is not None:
486+
upload_url = os.getenv("DIGITAL_OCEAN_URL") # Base URL for upload endpoint
487+
if not upload_url:
488+
raise GraphQLError("Upload URL not configured.")
489+
490+
payload = {
491+
"bucket": os.getenv("BUCKET_NAME", "DEV_BUCKET"),
492+
"image": encoded_image # Base64-encoded image string
493+
}
494+
headers = {"Content-Type": "application/json"}
495+
496+
print(f"Uploading image with payload: {payload}")
497+
498+
try:
499+
response = requests.post(upload_url, json=payload, headers=headers)
500+
response.raise_for_status()
501+
json_response = response.json()
502+
print(f"Upload API response: {json_response}")
503+
final_photo_url = json_response.get("data")
504+
if not final_photo_url:
505+
raise GraphQLError("No URL returned from upload service.")
506+
existing_user.encoded_image = final_photo_url
507+
except requests.exceptions.RequestException as e:
508+
print(f"Request failed: {e}")
509+
raise GraphQLError("Failed to upload photo.")
510+
511+
db_session.commit()
512+
return existing_user
445513

446514
class EnterGiveaway(graphene.Mutation):
447515
class Arguments:
@@ -598,6 +666,7 @@ def mutate(self, info, user_id):
598666
class Mutation(graphene.ObjectType):
599667
create_giveaway = CreateGiveaway.Field(description="Creates a new giveaway.")
600668
create_user = CreateUser.Field(description="Creates a new user.")
669+
edit_user = EditUser.Field(description="Edit a new user.")
601670
enter_giveaway = EnterGiveaway.Field(description="Enters a user into a giveaway.")
602671
set_workout_goals = SetWorkoutGoals.Field(description="Set a user's workout goals.")
603672
log_workout = logWorkout.Field(description="Log a user's workout.")

0 commit comments

Comments
 (0)