From 0f7f8ce7fcc4bfc8083c1b43e671fe426562ca66 Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Sat, 15 Apr 2023 16:19:29 -0400 Subject: [PATCH 01/39] Created activity model and many to many relationship with gym model; added activity and gym rresolvers to the schema --- src/app2/models/activity.py | 46 ++++++++++++++++++++++++++++++++++++ src/app2/models/gym.py | 4 +++- src/app2/schema.py | 47 +++++++++++++++++++++++++++++++++---- 3 files changed, 92 insertions(+), 5 deletions(-) create mode 100644 src/app2/models/activity.py diff --git a/src/app2/models/activity.py b/src/app2/models/activity.py new file mode 100644 index 0000000..4a7357e --- /dev/null +++ b/src/app2/models/activity.py @@ -0,0 +1,46 @@ +import datetime +from typing import Counter +from database import Base +from sqlalchemy import Table, Column, Integer, DateTime, ForeignKey, String, Boolean, null +from sqlalchemy.orm import relationship + +activities_to_gyms = Table( + "activities_to_gyms", + Base.metadata, + Column("gym_id", ForeignKey("gym.id"), primary_key=True), + Column("activity_id", ForeignKey("activity.id"), primary_key=True), +) + + +class Activity(Base): + __tablename__ = "activity" + + id = Column(Integer, primary_key=True) + name = Column(String(200), nullable=False) + details = Column(String(1000), nullable=False) + gyms = relationship('Gym', secondary=activities_to_gyms, + back_populates="activities") + #prices - rip + #amenities - rip + image_url = Column(String(1000), nullable=True) + + def __init__(self, **kwargs): + self.name = kwargs.get("name") + self.details = kwargs.get("details") + self.image_url = kwargs.get("image_url") + + +class Price(Base): + __tablename__ = "price" + + id = Column(Integer, primary_key=True) + name = Column(String(100), nullable=False) + cost = Column(Integer, nullable=False) + one_time = Column(Boolean, nullable=False) + image_url = Column(String(1000), nullable=True) + + def __init__(self, **kwargs): + self.name = kwargs.get("name") + self.cost = kwargs.get("cost") + self.one_time = kwargs.get("one_time") + self.image_url = kwargs.get("image_url") diff --git a/src/app2/models/gym.py b/src/app2/models/gym.py index 8883288..8eb9749 100644 --- a/src/app2/models/gym.py +++ b/src/app2/models/gym.py @@ -2,6 +2,7 @@ from database import Base from sqlalchemy import Column, DateTime, ForeignKey, Integer, String, Boolean, func from sqlalchemy.orm import backref, relationship +from models.activity import activities_to_gyms class Gym(Base): __tablename__ = "gym" @@ -9,7 +10,8 @@ class Gym(Base): id = Column(Integer, primary_key=True) name = Column(String(100), nullable=False) description = Column(String(1000), nullable=False) - # activities = relation + activities = relationship( + 'Activity', secondary=activities_to_gyms, back_populates="gyms") #facilties = relation times = relationship('GymTime', cascade='delete, all') #capacity = relation diff --git a/src/app2/schema.py b/src/app2/schema.py index 241c9dc..fd27361 100644 --- a/src/app2/schema.py +++ b/src/app2/schema.py @@ -1,5 +1,6 @@ from models.gym import Gym as GymModel, GymTime as GymTimeModel from models.daytime import DayTime as DayTimeModel +from models.activity import Activity as ActivityModel, Price as PriceModel import graphene from graphene import relay from graphene_sqlalchemy import SQLAlchemyConnectionField, SQLAlchemyObjectType @@ -10,6 +11,8 @@ class Meta: interfaces = (relay.Node,) times = graphene.List(lambda: DayTime, day=graphene.Int(), start_time=graphene.DateTime(), end_time=graphene.DateTime(), restrictions=graphene.String(), special_hours=graphene.Boolean()) + activities = graphene.List(lambda: Activity, name=graphene.String()) + #capacity = graphene.List(lambda: Capacity) def resolve_times(self, info, day=None, start_time=None, end_time=None): query = GymTime.get_query(info=info) @@ -29,21 +32,48 @@ def resolve_times(self, info, day=None, start_time=None, end_time=None): daytime_queries.append(daytime[0]) return daytime_queries + + def resolve_activities(self, info, name=None): + query = Activity.get_query(info=info) + activity_queries = [] + for act in self.activities: + activity = query.filter(ActivityModel.id == act.id) + if activity.first(): + if name and act.name == name: + activity_queries.append(activity[0]) + elif not name: + activity_queries.append(activity[0]) + return activity_queries class DayTime(SQLAlchemyObjectType): class Meta: model = DayTimeModel - interfaces = (relay.Node,) class GymTime(SQLAlchemyObjectType): class Meta: model = GymTimeModel - interfaces = (relay.Node,) - +class Activity(SQLAlchemyObjectType): + class Meta: + model = ActivityModel + + gyms = graphene.List(lambda: Gym, name=graphene.String()) + + def resolve_gyms(self, info, name=None): + query = Gym.get_query(info=info) + gym_queries = [] + for g in self.gyms: + gym = query.filter(GymModel.id == g.id) + if gym.first(): + if name and g.name == name: + gym_queries.append(gym[0]) + elif not name: + gym_queries.append(gym[0]) + return gym_queries + class Query(graphene.ObjectType): - node = relay.Node.Field() + # node = relay.Node.Field() # allowing single column sorting gyms = graphene.List(lambda: Gym, name=graphene.String(), description=graphene.String(), location=graphene.String(),image_url=graphene.String()) @@ -54,4 +84,13 @@ def resolve_gyms(self, info, name=None): query=query.filter(GymModel.name == name) return query.all() + activities = graphene.List(lambda: Activity, name=graphene.String( + ), details=graphene.String(), image_url=graphene.String()) + + def resolve_activities(self, info, name=None): + query = Activity.get_query(info) + if name: + query = query.filter(ActivityModel.name == name) + return query.all() + schema = graphene.Schema(query=Query) From 3878f6fe3c501e4a7838c7abfadb24590e53a663 Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Sat, 15 Apr 2023 16:22:08 -0400 Subject: [PATCH 02/39] added activity model to import statements on init_db() --- src/app2/database.py | 56 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/app2/database.py b/src/app2/database.py index 251973e..1120c70 100644 --- a/src/app2/database.py +++ b/src/app2/database.py @@ -15,6 +15,62 @@ def init_db(): # on metadata - otherwise import them first before calling init_db() from models.gym import Gym, GymTime from models.daytime import DayTime + from models.activity import Activity Base.metadata.drop_all(bind=engine) Base.metadata.create_all(bind=engine) + + Base.metadata.drop_all(bind=engine) + Base.metadata.create_all(bind=engine) + + gym_1 = Gym(name='Helen Newman', description='Something', + location='North', image_url='something') + db_session.add(gym_1) + daytime_1 = DayTime(day=1, start_time=datetime.datetime.utcnow( + ), end_time=datetime.datetime.utcnow(), restrictions='None', special_hours=True) + db_session.add(daytime_1) + db_session.commit() + + gymtime_1 = GymTime(daytime_id=daytime_1.id, gym_id=gym_1.id) + db_session.add(gymtime_1) + db_session.commit() + + activity_1 = Activity( + name='Volleyball', details='It fun', image_url='None') + db_session.add(activity_1) + db_session.commit() + + # adding the gym Helen Newman to the activity Volleyball + activity_1.gyms.append(gym_1) + db_session.add(activity_1) + db_session.commit() + + gym_2 = Gym(name="Morrison", description="Nicer", + location="North", image_url="N/A") + db_session.add(gym_2) + daytime_2 = DayTime(day=2, start_time=datetime.datetime.utcnow( + ), end_time=datetime.datetime.utcnow(), restrictions="A few", special_hours=False) + db_session.add(daytime_2) + db_session.commit() + + gymtime_2 = GymTime(daytime_id=daytime_2.id, gym_id=gym_2.id) + db_session.add(gymtime_2) + db_session.commit() + + activity_2 = Activity(name="Dancing", details="more fun", image_url="No") + db_session.add(activity_2) + db_session.commit() + + activity_2.gyms.append(gym_1) + activity_2.gyms.append(gym_2) + db_session.add(activity_2) + db_session.commit() + + # adding a few capacities + # capacity_1 = Capacity(gym_id=gym_1.id, current=10, + # maximum=70, last_updated=datetime.datetime.utcnow()) + # capacity_2 = Capacity(gym_id=gym_2.id, current=20, + # maximum=100, last_updated=datetime.datetime.utcnow()) + # db_session.add(capacity_1) + # db_session.add(capacity_2) + # db_session.commit() From 9936f9f39d76660c688562b0937be24dc9cfd03a Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Sat, 15 Apr 2023 16:23:06 -0400 Subject: [PATCH 03/39] deleted testing objects in init_db() --- src/app2/database.py | 52 +------------------------------------------- 1 file changed, 1 insertion(+), 51 deletions(-) diff --git a/src/app2/database.py b/src/app2/database.py index 1120c70..1215b7d 100644 --- a/src/app2/database.py +++ b/src/app2/database.py @@ -23,54 +23,4 @@ def init_db(): Base.metadata.drop_all(bind=engine) Base.metadata.create_all(bind=engine) - gym_1 = Gym(name='Helen Newman', description='Something', - location='North', image_url='something') - db_session.add(gym_1) - daytime_1 = DayTime(day=1, start_time=datetime.datetime.utcnow( - ), end_time=datetime.datetime.utcnow(), restrictions='None', special_hours=True) - db_session.add(daytime_1) - db_session.commit() - - gymtime_1 = GymTime(daytime_id=daytime_1.id, gym_id=gym_1.id) - db_session.add(gymtime_1) - db_session.commit() - - activity_1 = Activity( - name='Volleyball', details='It fun', image_url='None') - db_session.add(activity_1) - db_session.commit() - - # adding the gym Helen Newman to the activity Volleyball - activity_1.gyms.append(gym_1) - db_session.add(activity_1) - db_session.commit() - - gym_2 = Gym(name="Morrison", description="Nicer", - location="North", image_url="N/A") - db_session.add(gym_2) - daytime_2 = DayTime(day=2, start_time=datetime.datetime.utcnow( - ), end_time=datetime.datetime.utcnow(), restrictions="A few", special_hours=False) - db_session.add(daytime_2) - db_session.commit() - - gymtime_2 = GymTime(daytime_id=daytime_2.id, gym_id=gym_2.id) - db_session.add(gymtime_2) - db_session.commit() - - activity_2 = Activity(name="Dancing", details="more fun", image_url="No") - db_session.add(activity_2) - db_session.commit() - - activity_2.gyms.append(gym_1) - activity_2.gyms.append(gym_2) - db_session.add(activity_2) - db_session.commit() - - # adding a few capacities - # capacity_1 = Capacity(gym_id=gym_1.id, current=10, - # maximum=70, last_updated=datetime.datetime.utcnow()) - # capacity_2 = Capacity(gym_id=gym_2.id, current=20, - # maximum=100, last_updated=datetime.datetime.utcnow()) - # db_session.add(capacity_1) - # db_session.add(capacity_2) - # db_session.commit() + From 0e495a17a98a20eaa7b7484275ed81c74678be34 Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Sat, 15 Apr 2023 16:24:32 -0400 Subject: [PATCH 04/39] deleted duplicate code --- src/app2/database.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/app2/database.py b/src/app2/database.py index 1215b7d..af5a6fc 100644 --- a/src/app2/database.py +++ b/src/app2/database.py @@ -20,7 +20,4 @@ def init_db(): Base.metadata.drop_all(bind=engine) Base.metadata.create_all(bind=engine) - Base.metadata.drop_all(bind=engine) - Base.metadata.create_all(bind=engine) - From e7f65f524e15d938618f02577ad107e1629f5779 Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Wed, 19 Apr 2023 19:25:21 -0400 Subject: [PATCH 05/39] Implemented PR edits in activity.py --- src/app2/models/activity.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/app2/models/activity.py b/src/app2/models/activity.py index 4a7357e..470535f 100644 --- a/src/app2/models/activity.py +++ b/src/app2/models/activity.py @@ -16,12 +16,12 @@ class Activity(Base): __tablename__ = "activity" id = Column(Integer, primary_key=True) - name = Column(String(200), nullable=False) + name = Column(String(), nullable=False) details = Column(String(1000), nullable=False) gyms = relationship('Gym', secondary=activities_to_gyms, back_populates="activities") - #prices - rip - #amenities - rip + prices = relationship('Price', cascade='delete, all') + amenities = relationship('Amenity', cascade='delete, all') image_url = Column(String(1000), nullable=True) def __init__(self, **kwargs): @@ -38,9 +38,25 @@ class Price(Base): cost = Column(Integer, nullable=False) one_time = Column(Boolean, nullable=False) image_url = Column(String(1000), nullable=True) + activity_id = Column(Integer, ForeignKey('activity.id'), nullable=False) def __init__(self, **kwargs): self.name = kwargs.get("name") self.cost = kwargs.get("cost") self.one_time = kwargs.get("one_time") self.image_url = kwargs.get("image_url") + self.activity_id = kwargs.get("activity_id") + + +class Amenity(Base): + __tablename__ = 'amenity' + + id = Column(Integer, primary_key=True) + name = Column(String(), nullable=False) + image_url = Column(String(), nullable=True) + activity_id = Column(Integer, ForeignKey('activity.id'), nullable=False) + + def __init__(self, **kwargs): + self.name = kwargs.get("name") + self.image_url = kwargs.get("image_url") + self.activity_id = kwargs.get("activity_id") From bacd3ae43301f8f28b4ee87ee6fa57fee59d4122 Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Wed, 19 Apr 2023 19:26:09 -0400 Subject: [PATCH 06/39] Implemented PR edits in gym.py --- src/app2/models/gym.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/app2/models/gym.py b/src/app2/models/gym.py index 8eb9749..51b2466 100644 --- a/src/app2/models/gym.py +++ b/src/app2/models/gym.py @@ -12,9 +12,7 @@ class Gym(Base): description = Column(String(1000), nullable=False) activities = relationship( 'Activity', secondary=activities_to_gyms, back_populates="gyms") - #facilties = relation times = relationship('GymTime', cascade='delete, all') - #capacity = relation location=Column(String(1000), nullable=False) image_url = Column(String(1000), nullable=True) From 34f79d5ad64d24270e60458d7ad1a3c51c34413c Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Wed, 19 Apr 2023 19:27:10 -0400 Subject: [PATCH 07/39] Implemented PR changes in schema.py and added Price and Amenity class and price resolver in Activity class --- src/app2/schema.py | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/app2/schema.py b/src/app2/schema.py index fd27361..62f0bbe 100644 --- a/src/app2/schema.py +++ b/src/app2/schema.py @@ -1,6 +1,7 @@ from models.gym import Gym as GymModel, GymTime as GymTimeModel from models.daytime import DayTime as DayTimeModel from models.activity import Activity as ActivityModel, Price as PriceModel +from models.activity import Amenity as AmenityModel import graphene from graphene import relay from graphene_sqlalchemy import SQLAlchemyConnectionField, SQLAlchemyObjectType @@ -8,11 +9,9 @@ class Gym(SQLAlchemyObjectType): class Meta: model = GymModel - interfaces = (relay.Node,) times = graphene.List(lambda: DayTime, day=graphene.Int(), start_time=graphene.DateTime(), end_time=graphene.DateTime(), restrictions=graphene.String(), special_hours=graphene.Boolean()) activities = graphene.List(lambda: Activity, name=graphene.String()) - #capacity = graphene.List(lambda: Capacity) def resolve_times(self, info, day=None, start_time=None, end_time=None): query = GymTime.get_query(info=info) @@ -38,10 +37,7 @@ def resolve_activities(self, info, name=None): activity_queries = [] for act in self.activities: activity = query.filter(ActivityModel.id == act.id) - if activity.first(): - if name and act.name == name: - activity_queries.append(activity[0]) - elif not name: + if activity.first() and (name == act.name or name == None): activity_queries.append(activity[0]) return activity_queries @@ -58,23 +54,37 @@ class Meta: model = ActivityModel gyms = graphene.List(lambda: Gym, name=graphene.String()) + prices = graphene.List(lambda: Price, cost=graphene.Int(), one_time=graphene.Boolean()) def resolve_gyms(self, info, name=None): query = Gym.get_query(info=info) gym_queries = [] for g in self.gyms: gym = query.filter(GymModel.id == g.id) - if gym.first(): - if name and g.name == name: - gym_queries.append(gym[0]) - elif not name: - gym_queries.append(gym[0]) + if gym.first() and (name == g.name or name == None): + gym_queries.append(gym[0]) + return gym_queries + def resolve_prices(self, info, cost=None, one_time=None): + query = Price.get_query(info=info) + query = query.filter(PriceModel.activity_id == self.id) + if cost: + query = query.filter(PriceModel.cost == cost) + if one_time != None: + query = query.filter(PriceModel.one_time == one_time) + return query + +class Price(SQLAlchemyObjectType): + class Meta: + model = PriceModel + +class Amenity(SQLAlchemyObjectType): + class Meta: + model = AmenityModel + class Query(graphene.ObjectType): - # node = relay.Node.Field() - # allowing single column sorting gyms = graphene.List(lambda: Gym, name=graphene.String(), description=graphene.String(), location=graphene.String(),image_url=graphene.String()) @@ -84,8 +94,8 @@ def resolve_gyms(self, info, name=None): query=query.filter(GymModel.name == name) return query.all() - activities = graphene.List(lambda: Activity, name=graphene.String( - ), details=graphene.String(), image_url=graphene.String()) + activities = graphene.List(lambda: Activity, name=graphene.String( \ + ), details=graphene.String(), image_url=graphene.String()) def resolve_activities(self, info, name=None): query = Activity.get_query(info) From 045ae0cd1c9f3feb5c9e8a42a77e01280e4bc477 Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Thu, 20 Apr 2023 12:12:26 -0400 Subject: [PATCH 08/39] Populated models to test --- src/app2/database.py | 66 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/src/app2/database.py b/src/app2/database.py index af5a6fc..6b7befa 100644 --- a/src/app2/database.py +++ b/src/app2/database.py @@ -15,9 +15,73 @@ def init_db(): # on metadata - otherwise import them first before calling init_db() from models.gym import Gym, GymTime from models.daytime import DayTime - from models.activity import Activity + from models.activity import Activity, Price, Amenity Base.metadata.drop_all(bind=engine) Base.metadata.create_all(bind=engine) + gym_1 = Gym(name='Helen Newman', description='Something', + location='North', image_url='something') + db_session.add(gym_1) + daytime_1 = DayTime(day=1, start_time=datetime.datetime.utcnow( + ), end_time=datetime.datetime.utcnow(), restrictions='None', special_hours=True) + db_session.add(daytime_1) + db_session.commit() + + gymtime_1 = GymTime(daytime_id=daytime_1.id, gym_id=gym_1.id) + db_session.add(gymtime_1) + db_session.commit() + + activity_1 = Activity( + name='Volleyball', details='It fun', image_url='None') + db_session.add(activity_1) + db_session.commit() + + # adding the gym Helen Newman to the activity Volleyball + activity_1.gyms.append(gym_1) + db_session.add(activity_1) + db_session.commit() + + price_1 = Price(name="price1", cost=20, one_time=False, image_url="none", activity_id=activity_1.id) + db_session.add(price_1) + db_session.commit() + activity_1.prices.append(price_1) + db_session.add(activity_1) + db_session.commit() + + price_2 = Price(name="price2", cost=40, one_time=True, image_url="n/a", activity_id = activity_1.id) + db_session.add(price_2) + db_session.commit() + activity_1.prices.append(price_2) + db_session.add(activity_1) + db_session.commit() + + amenity_1 = Amenity(name="locker", image_url="none", activity_id=activity_1.id) + db_session.add(amenity_1) + db_session.commit() + activity_1.amenities.append(amenity_1) + db_session.add(activity_1) + db_session.commit() + + gym_2 = Gym(name="Morrison", description="Nicer", + location="North", image_url="N/A") + db_session.add(gym_2) + daytime_2 = DayTime(day=2, start_time=datetime.datetime.utcnow( + ), end_time=datetime.datetime.utcnow(), restrictions="A few", special_hours=False) + db_session.add(daytime_2) + db_session.commit() + + gymtime_2 = GymTime(daytime_id=daytime_2.id, gym_id=gym_2.id) + db_session.add(gymtime_2) + db_session.commit() + + activity_2 = Activity(name="Dancing", details="more fun", image_url="No") + db_session.add(activity_2) + db_session.commit() + + activity_2.gyms.append(gym_1) + activity_2.gyms.append(gym_2) + db_session.add(activity_2) + db_session.commit() + From 25669b1e5549a7bc24a1421f93f3596fdc6fc6ec Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Sun, 30 Apr 2023 22:15:11 -0400 Subject: [PATCH 09/39] Cleaning up some merge conflicts --- src/uplift/database.py | 2 +- src/uplift/models/gym.py | 8 ++++---- src/uplift/schema.py | 9 --------- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/uplift/database.py b/src/uplift/database.py index 964eaba..511c6e3 100644 --- a/src/uplift/database.py +++ b/src/uplift/database.py @@ -86,7 +86,7 @@ def create_gym_table(): gyms = [ helen_newman, noyes, - morrison, + # morrison, teagle_up, teagle_down ] diff --git a/src/uplift/models/gym.py b/src/uplift/models/gym.py index 1d61fbd..14e4a86 100644 --- a/src/uplift/models/gym.py +++ b/src/uplift/models/gym.py @@ -8,16 +8,16 @@ class Gym(Base): __tablename__ = "gym" id = Column(Integer, primary_key=True) - name = Column(String(100), nullable=False) - description = Column(String(1000), nullable=False) + name = Column(String(), nullable=False) + description = Column(String(), nullable=False) activities = relationship( 'Activity', secondary=activities_to_gyms, back_populates="gyms") times = relationship('GymTime', cascade='delete, all') capacity = relationship('Capacity', cascade='delete, all') - location=Column(String(1000), nullable=False) + location=Column(String(), nullable=False) latitude=Column(Integer, nullable=False) longitude=Column(Float, nullable=False) - image_url = Column(String(1000), nullable=True) + image_url = Column(String(), nullable=True) def __init__(self, **kwargs): self.id=kwargs.get("id") diff --git a/src/uplift/schema.py b/src/uplift/schema.py index 70dd220..aed007a 100644 --- a/src/uplift/schema.py +++ b/src/uplift/schema.py @@ -88,15 +88,6 @@ class Meta: model = CapacityModel - def resolve_prices(self, info, cost=None, one_time=None): - query = Price.get_query(info=info) - query = query.filter(PriceModel.activity_id == self.id) - if cost: - query = query.filter(PriceModel.cost == cost) - if one_time is not None: - query = query.filter(PriceModel.one_time == one_time) - return query - class Price(SQLAlchemyObjectType): class Meta: model = PriceModel From 2eebca9348442cd02a5a0ee7272389e16400b130 Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Mon, 28 Aug 2023 17:43:25 -0400 Subject: [PATCH 10/39] almost implementing Facilities --- src/app2/database.py | 3 +- src/app2/database.py.orig | 91 +++++++++++++++++ src/app2/database.sqlite3 | Bin 0 -> 36864 bytes src/appdev-py | 1 + src/uplift/database.py | 140 +++++++++++++++++++++++++- src/uplift/database.sqlite3 | Bin 20480 -> 40960 bytes src/uplift/models/activity.py | 23 ++--- src/uplift/models/facility.py | 66 +++++++++++++ src/uplift/models/gym.py | 27 ++---- src/uplift/models/price.py | 19 ++++ src/uplift/schema.py | 178 +++++++++++++++++++++++++--------- 11 files changed, 465 insertions(+), 83 deletions(-) create mode 100644 src/app2/database.py.orig create mode 100644 src/app2/database.sqlite3 create mode 160000 src/appdev-py create mode 100644 src/uplift/models/facility.py create mode 100644 src/uplift/models/price.py diff --git a/src/app2/database.py b/src/app2/database.py index a5831ee..a676da0 100644 --- a/src/app2/database.py +++ b/src/app2/database.py @@ -84,8 +84,7 @@ def init_db(): db_session.add(activity_2) db_session.commit() -def merge(): - pass + diff --git a/src/app2/database.py.orig b/src/app2/database.py.orig new file mode 100644 index 0000000..a5831ee --- /dev/null +++ b/src/app2/database.py.orig @@ -0,0 +1,91 @@ +from sqlalchemy import create_engine +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import scoped_session, sessionmaker +import datetime + +engine = create_engine("sqlite:///database.sqlite3") +db_session = scoped_session( + sessionmaker(autocommit=False, autoflush=False, bind=engine) +) +Base = declarative_base() +Base.query = db_session.query_property() + +def init_db(): + # import all modules that might define models so they will be registered properly + # on metadata - otherwise import them first before calling init_db() + from models.gym import Gym, GymTime + from models.daytime import DayTime + from models.activity import Activity, Price, Amenity + + Base.metadata.drop_all(bind=engine) + Base.metadata.create_all(bind=engine) + + gym_1 = Gym(name='Helen Newman', description='Something', + location='North', image_url='something') + db_session.add(gym_1) + daytime_1 = DayTime(day=1, start_time=datetime.datetime.utcnow( + ), end_time=datetime.datetime.utcnow(), restrictions='None', special_hours=True) + db_session.add(daytime_1) + db_session.commit() + + gymtime_1 = GymTime(daytime_id=daytime_1.id, gym_id=gym_1.id) + db_session.add(gymtime_1) + db_session.commit() + + activity_1 = Activity( + name='Volleyball', details='It fun', image_url='None') + db_session.add(activity_1) + db_session.commit() + + # adding the gym Helen Newman to the activity Volleyball + activity_1.gyms.append(gym_1) + db_session.add(activity_1) + db_session.commit() + + price_1 = Price(name="price1", cost=20, one_time=False, image_url="none", activity_id=activity_1.id) + db_session.add(price_1) + db_session.commit() + activity_1.prices.append(price_1) + db_session.add(activity_1) + db_session.commit() + + price_2 = Price(name="price2", cost=40, one_time=True, image_url="n/a", activity_id = activity_1.id) + db_session.add(price_2) + db_session.commit() + activity_1.prices.append(price_2) + db_session.add(activity_1) + db_session.commit() + + amenity_1 = Amenity(name="locker", image_url="none", activity_id=activity_1.id) + db_session.add(amenity_1) + db_session.commit() + activity_1.amenities.append(amenity_1) + db_session.add(activity_1) + db_session.commit() + + gym_2 = Gym(name="Morrison", description="Nicer", + location="North", image_url="N/A") + db_session.add(gym_2) + daytime_2 = DayTime(day=2, start_time=datetime.datetime.utcnow( + ), end_time=datetime.datetime.utcnow(), restrictions="A few", special_hours=False) + db_session.add(daytime_2) + db_session.commit() + + gymtime_2 = GymTime(daytime_id=daytime_2.id, gym_id=gym_2.id) + db_session.add(gymtime_2) + db_session.commit() + + activity_2 = Activity(name="Dancing", details="more fun", image_url="No") + db_session.add(activity_2) + db_session.commit() + + activity_2.gyms.append(gym_1) + activity_2.gyms.append(gym_2) + db_session.add(activity_2) + db_session.commit() + +def merge(): + pass + + + diff --git a/src/app2/database.sqlite3 b/src/app2/database.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..515f80ebcd7abd62e216633e0a5994606f941598 GIT binary patch literal 36864 zcmeI*?QhdY90%|_Cr#p_;6ayJRaJ3&F)0xR@<3TZnwSZOMzjt~J0`Rjkx5Kz&9OV% z9jnwgwER)L+WvyQ+zX_=JoGTs?M^=-pD?c~#hTw(_`}kHRj6Ve13K zHvPSLRY-*$S567r=3Ur5rPEwh(jMkO-!i(pu9dU~Vd*{J{D!~Tzoi)3J{4S2A4hnw zlFQ4oOrNyF2zOkwXM~GhDWrYB{sCtNTgApRFJ%C>^K?T&G6Vt>f?NB&gA4TYLu9E z-}u)1+Txc+U47Sg!q?rn^N>-uHd>eCvsfXR$qq`HaQHo;VRFX9I9_E_mM@3+v{`2? zn&<1TA7$Z9K8tO(*40!R8g_q5t7~{ZA2Yt`*j_SxkMh*pF?yzMb+?^e*BhJUsZ$ou zXmO^dH$F;NJ}q^GygWBY4^JhtF+XdWlt*|PCt3_oMWe&DZ+Jb|+zDbzhm>-$oSyy< zU8aoSSL5bEEz`WbxJVB^iRRjP{!8*pNQIZwzUGvaI`F>X>!$U}*-G_zqvI~}L=~hT zi1eH4uD5N622;+dPe-81d2f#dRj?C;u|Gf!v8 zhx4U-j%68p4|L0F`B8&yMA!dMiS(oN^z9E2M+gB3KmY;|fB*y_009U<00Iy=Spo|} zjx5UZ+`8ksrsvoizw^n}9M|90E-4k7BOjfU&#fAkVKdEmG|=r0XJGi-{9}Qzlb5`T zuK)Lm^u4ryvIG$=1Rwwb2tWV=5P$##AOHafK;ZuoP=q|8iXs<;dbQrTP`!MieudTR z*BV!^RWDz>^6_%Lwlb-u-cZ;>DLo=c{%VWw&FM{j;-}njz z0uX=z1Rwwb2tWV=5P$##AOL}5E|AaC;Oak<%ZlNr09jEKqx=7#5$T2W?3jm#!-oI_ zAOHafKmY;|fB*y_009V`Jb^R(%LVgPoD;(zKdG1POZr*oh(J!rlJNF_nkAz6H{@J=*8l(j literal 0 HcmV?d00001 diff --git a/src/appdev-py b/src/appdev-py new file mode 160000 index 0000000..fffe58a --- /dev/null +++ b/src/appdev-py @@ -0,0 +1 @@ +Subproject commit fffe58a01ba5bc00493213e2baa00a6a9e393280 diff --git a/src/uplift/database.py b/src/uplift/database.py index 511c6e3..ab905d4 100644 --- a/src/uplift/database.py +++ b/src/uplift/database.py @@ -19,7 +19,119 @@ def init_db(): # import all modules that might define models so they will be registered properly # on metadata - otherwise import them first before calling init_db() Base.metadata.create_all(bind=engine) - create_gym_table() + def init_db(): + # import all modules that might define models so they will be registered properly + # on metadata - otherwise import them first before calling init_db() + from models.gym import Gym, GymTime + from models.daytime import DayTime + from models.activity import Activity, Amenity, ActivityPrice + from models.price import Price + from models.facility import Facility, FacilityTime, Equipment, FacilityPrice + + Base.metadata.drop_all(bind=engine) + Base.metadata.create_all(bind=engine) + + gym_1 = Gym(name='Helen Newman', description='Something', + location='North', image_url='something') + db_session.add(gym_1) + daytime_1 = DayTime(day=1, start_time=datetime.datetime.utcnow( + ), end_time=datetime.datetime.utcnow(), restrictions='None', special_hours=True) + db_session.add(daytime_1) + db_session.commit() + + gymtime_1 = GymTime(daytime_id=daytime_1.id, gym_id=gym_1.id) + db_session.add(gymtime_1) + db_session.commit() + + activity_1 = Activity( + name='Volleyball', details='It fun', image_url='None') + db_session.add(activity_1) + db_session.commit() + + # adding the gym Helen Newman to the activity Volleyball + activity_1.gyms.append(gym_1) + db_session.add(activity_1) + db_session.commit() + + price_1 = Price(name="price1", cost=20, one_time=False, image_url="none") + db_session.add(price_1) + db_session.commit() + + price_2 = Price(name="price2", cost=40, one_time=True, image_url="n/a") + db_session.add(price_2) + db_session.commit() + + price_3=Price(name="price3", cost=50, one_time=False, image_url="none") + price_4=Price(name="price4", cost=15, one_time=False, image_url="n/a") + db_session.add(price_3) + db_session.add(price_4) + db_session.commit() + + activityprice_1 = ActivityPrice(activity_id=activity_1.id, price_id=price_1.id) + activityprice_2=ActivityPrice(activity_id=activity_1.id, price_id=price_2.id) + db_session.add(activityprice_1) + db_session.add(activityprice_2) + db_session.commit() + + + amenity_1 = Amenity(name="locker", image_url="none", activity_id=activity_1.id) + db_session.add(amenity_1) + db_session.commit() + activity_1.amenities.append(amenity_1) + db_session.add(activity_1) + db_session.commit() + + facility_1 = Facility(name="basketball court", image_url="None") + db_session.add(facility_1) + db_session.commit() + + facility_2 = Facility(name="beach volleyball court", image_url="N/A") + db_session.add(facility_2) + db_session.commit() + + facilitytime_1 = FacilityTime(facility_id=facility_1.id, daytime_id=daytime_1.id) + db_session.add(facilitytime_1) + db_session.commit() + + facilityprice_1 = FacilityPrice(facility_id=facility_1.id, price_id=price_3.id) + facilityprice_2 = FacilityPrice(facility_id=facility_1.id, price_id=price_4.id) + db_session.add(facilityprice_1) + db_session.add(facilityprice_2) + db_session.commit() + + equipment_1 = Equipment(equipment_type="Exercise machine", name="Squat Rack 1", quantity=2, facility_id=facility_1.id, image_url="n/a") + db_session.add(equipment_1) + db_session.commit() + + equipment_2 = Equipment(equipment_type="Exercise thingy", name="Dumbbell", quantity=20, facility_id=facility_1.id, image_url="none") + db_session.add(equipment_2) + db_session.commit() + + gym_2 = Gym(name="Morrison", description="Nicer", + location="North", image_url="N/A") + db_session.add(gym_2) + daytime_2 = DayTime(day=2, start_time=datetime.datetime.utcnow( + ), end_time=datetime.datetime.utcnow(), restrictions="A few", special_hours=False) + db_session.add(daytime_2) + db_session.commit() + + facilitytime_2 = FacilityTime(facility_id=facility_2.id, daytime_id=daytime_2.id) + db_session.add(facilitytime_2) + db_session.commit() + + gymtime_2 = GymTime(daytime_id=daytime_2.id, gym_id=gym_2.id) + db_session.add(gymtime_2) + db_session.commit() + + activity_2 = Activity(name="Dancing", details="more fun", image_url="No") + db_session.add(activity_2) + db_session.commit() + + activity_2.gyms.append(gym_1) + activity_2.gyms.append(gym_2) + db_session.add(activity_2) + db_session.commit() + """ @@ -94,3 +206,29 @@ def create_gym_table(): for gym in gyms: db_session.merge(gym) +def create_activities_table(): + from models.activity import Activity, Amenity + from models.daytime import DayTime + + basketball = Activity(name = "Basketball", + details="details", + image_url="None" + ) + + beach_volleyball = Activity( + name="Beach Volleyball", + details="details", + image_url="N/A" + ) + + activities = [ + basketball, + beach_volleyball + ] + + for act in activities: + db_session.merge(act) + + + + diff --git a/src/uplift/database.sqlite3 b/src/uplift/database.sqlite3 index 029e9468451ce2c1c20e17a7d1ed72ef0b0ee34c..b9e861547174b89d3e45b9e1b074e22e3e8a3ca9 100644 GIT binary patch delta 971 zcma))y>HV%7{={3sbj}?mqb(^Oxi0`f|AJ2hgu?0e{)ApJ`>(q?lkJ);BZwm1 zn|G?$8&-AGYTC~BaN$aZs#H{5QP#>T9*TsABHwg3_=;kb&MOA_gcd*wb8NNd*mvD% zlSH6E-os<$0pN|XYS)w4P}fyM)k^9mJkoK({lO)7S3-;+2=qhU1G#m_u36rPJpwV1 zNEjX`IkXU{wb~9j!_P-rP0Ms_7imq`%c`QeNQo&Nu`{-9XgDFIu$)W|xYu<<-8iS= z3+lDRh|2s2ZETJaWSQE{7HpNN4y z3VlcK&=a(U3?v}{58!9`0`_1PuEIF@1-^neV6Pv=H$Z187NlrenMr1)Y%VS3(>V!e zAM2EI?cw|E}&uxwTon83Z5 xg~vpWm(PxY{~rHt{u%tG{6YK%{Jeax_)hRG<7?(is360)+0O3}BLL7B75D%E diff --git a/src/uplift/models/activity.py b/src/uplift/models/activity.py index 470535f..58c5431 100644 --- a/src/uplift/models/activity.py +++ b/src/uplift/models/activity.py @@ -1,4 +1,5 @@ import datetime +from importlib.machinery import FrozenImporter from typing import Counter from database import Base from sqlalchemy import Table, Column, Integer, DateTime, ForeignKey, String, Boolean, null @@ -17,36 +18,28 @@ class Activity(Base): id = Column(Integer, primary_key=True) name = Column(String(), nullable=False) - details = Column(String(1000), nullable=False) + details = Column(String(), nullable=False) gyms = relationship('Gym', secondary=activities_to_gyms, back_populates="activities") - prices = relationship('Price', cascade='delete, all') + prices = relationship('ActivityPrice', cascade='delete, all') amenities = relationship('Amenity', cascade='delete, all') - image_url = Column(String(1000), nullable=True) + image_url = Column(String(), nullable=True) def __init__(self, **kwargs): self.name = kwargs.get("name") self.details = kwargs.get("details") self.image_url = kwargs.get("image_url") - -class Price(Base): - __tablename__ = "price" +class ActivityPrice(Base): + __tablename__ = "activityprice" id = Column(Integer, primary_key=True) - name = Column(String(100), nullable=False) - cost = Column(Integer, nullable=False) - one_time = Column(Boolean, nullable=False) - image_url = Column(String(1000), nullable=True) activity_id = Column(Integer, ForeignKey('activity.id'), nullable=False) + price_id = Column(Integer, ForeignKey('price.id'), nullable=False) def __init__(self, **kwargs): - self.name = kwargs.get("name") - self.cost = kwargs.get("cost") - self.one_time = kwargs.get("one_time") - self.image_url = kwargs.get("image_url") self.activity_id = kwargs.get("activity_id") - + self.price = kwargs.get("price_id") class Amenity(Base): __tablename__ = 'amenity' diff --git a/src/uplift/models/facility.py b/src/uplift/models/facility.py new file mode 100644 index 0000000..ceec403 --- /dev/null +++ b/src/uplift/models/facility.py @@ -0,0 +1,66 @@ +from ast import For +from database import Base +from sqlalchemy import Column, DateTime, ForeignKey, Integer, Float, String, func +from sqlalchemy.orm import backref, relationship +from models.price import Price + + +class Facility(Base): + __tablename__ = "facility" + + id = Column(Integer, primary_key=True) + name = Column(String(), nullable=False) + times = relationship('FacilityTime', cascade='delete, all') + price = relationship('Price', cascade='delete, all') + equipment = relationship('Equipment', cascade='delete, all') + image_url = Column(String(), nullable=True) + + def __init__(self, **kwargs): + self.name = kwargs.get("name") + self.image_url = kwargs.get("image") + + +class FacilityTime(Base): + __tablename__ = "facilitytime" + + id = Column(Integer, primary_key=True) + facilty_id = Column(Integer, ForeignKey('facility.id'), nullable=False) + daytime_id = Column(Integer, ForeignKey('daytime.id'), nullable=False) + + def __init__(self, **kwargs): + self.facility_id = kwargs.get("facility_id") + self.daytime_id = kwargs.get("daytime_id") + +class FacilityPrice(Base): + __tablename__ = "facilityprice" + + id = Column(Integer, primary_key=True) + facility_id = Column(Integer, ForeignKey('facility.id'), nullable=False) + price_id = Column(Integer, ForeignKey('price.id'), nullable=False) + + def __init__(self, **kwargs): + self.facility_id=kwargs.get("facility_id") + self.price_id=kwargs.get("price_id") + + +class Equipment(Base): + __tablename__ = "equipment" + + id = Column(Integer, primary_key=True) + equipment_type = Column(String(), nullable=False) + name = Column(String(), nullable=False) + quantity = Column(Integer, nullable=False) + facility_id = Column(Integer, ForeignKey('facility.id'), nullable=False) + + def __init__(self, **kwargs): + self.equipment_type = kwargs.get("equipment_type") + self.name = kwargs.get("name") + self.quantity = kwargs.get("quantity") + self.facility_id=kwargs.get("facility_id") + + + + + + + diff --git a/src/uplift/models/gym.py b/src/uplift/models/gym.py index 14e4a86..495ba08 100644 --- a/src/uplift/models/gym.py +++ b/src/uplift/models/gym.py @@ -2,6 +2,7 @@ from database import Base from sqlalchemy import Column, DateTime, ForeignKey, Integer, Float, String, Boolean, func from sqlalchemy.orm import backref, relationship +from models.facility import Facility from models.activity import activities_to_gyms class Gym(Base): @@ -12,33 +13,23 @@ class Gym(Base): description = Column(String(), nullable=False) activities = relationship( 'Activity', secondary=activities_to_gyms, back_populates="gyms") + facilities = relationship('Facility', cascade='delete, all') times = relationship('GymTime', cascade='delete, all') capacity = relationship('Capacity', cascade='delete, all') - location=Column(String(), nullable=False) - latitude=Column(Integer, nullable=False) - longitude=Column(Float, nullable=False) + location = Column(String(), nullable=False) + latitude = Column(Integer, nullable=False) + longitude = Column(Float, nullable=False) image_url = Column(String(), nullable=True) def __init__(self, **kwargs): - self.id=kwargs.get("id") + self.id = kwargs.get("id") self.name = kwargs.get("name") self.description = kwargs.get("description") - self.location=kwargs.get("location") + self.location = kwargs.get("location") self.latitude = kwargs.get('latitude') self.longitude = kwargs.get('longitude') self.image_url = kwargs.get("image_url") - def serialize(self): - return { - "id":self.id, - "name": self.name, - "description": self.description, - "location": self.location, - "latitude": self.latitude, - "longitude":self.longitude, - "image_url": self.image_url - } - class GymTime(Base): __tablename__ = 'gymtime' @@ -56,7 +47,3 @@ def serialize(self): "daytime_id": self.daytime_id, "gym_id": self.gym_id } - - - - diff --git a/src/uplift/models/price.py b/src/uplift/models/price.py new file mode 100644 index 0000000..44ee4da --- /dev/null +++ b/src/uplift/models/price.py @@ -0,0 +1,19 @@ +from database import Base +from sqlalchemy import Column, String, Integer, ForeignKey, Boolean +from sqlalchemy.orm import relationship + +class Price(Base): + __tablename__ = "price" + + id = Column(Integer, primary_key=True) + name = Column(String(), nullable=False) + cost = Column(Integer, nullable=False) + one_time = Column(Boolean, nullable=False) + image = Column(String(), nullable=True) + + def __init__(self, **kwargs): + self.name = kwargs.get("name") + self.cost = kwargs.get("cost") + self.one_time = kwargs.get("one_time") + self.image = kwargs.get("image") + diff --git a/src/uplift/schema.py b/src/uplift/schema.py index aed007a..d3b1da8 100644 --- a/src/uplift/schema.py +++ b/src/uplift/schema.py @@ -1,13 +1,15 @@ -import datetime as dt - +import datetime as dt +from socketserver import StreamRequestHandler +from xml.sax.handler import property_declaration_handler from graphene import Field, ObjectType, String, List, Int, Boolean from graphene.types.datetime import Date, Time - from models.gym import Gym as GymModel, GymTime as GymTimeModel from models.daytime import DayTime as DayTimeModel -from models.activity import Activity as ActivityModel, Price as PriceModel +from models.activity import Activity as ActivityModel, ActivityPrice as ActivityPriceModel from models.capacity import Capacity as CapacityModel from models.activity import Amenity as AmenityModel +from models.price import Price as PriceModel +from models.facility import Facility as FacilityModel, FacilityPrice as FacilityPriceModel, Equipment as EquipmentModel, FacilityTime as FacilityTimeModel import graphene from graphene import relay from graphene_sqlalchemy import SQLAlchemyConnectionField, SQLAlchemyObjectType @@ -18,7 +20,8 @@ class Gym(SQLAlchemyObjectType): class Meta: model = GymModel - times = graphene.List(lambda: DayTime, day=graphene.Int(), start_time=graphene.DateTime(), end_time=graphene.DateTime(), restrictions=graphene.String(), special_hours=graphene.Boolean()) + times = graphene.List(lambda: DayTime, day=graphene.Int(), start_time=graphene.DateTime( + ), end_time=graphene.DateTime(), restrictions=graphene.String(), special_hours=graphene.Boolean()) activities = graphene.List(lambda: Activity, name=graphene.String()) capacities = graphene.List(lambda: Capacity, gym_id=graphene.Int()) @@ -26,19 +29,19 @@ class Meta: def resolve_times(self, info, day=None, start_time=None, end_time=None): query = GymTime.get_query(info=info) query = query.filter(GymTimeModel.gym_id == self.id) - query_daytime = DayTime.get_query(info=info) #could be wrong + query_daytime = DayTime.get_query(info=info) # could be wrong if day: - query_daytime = query_daytime.filter(DayTimeModel.day == day) + query_daytime = query_daytime.filter(DayTimeModel.day == day) if start_time: - query_daytime = query_daytime.filter(DayTimeModel.start_time == start_time) + query_daytime = query_daytime.filter(DayTimeModel.start_time == start_time) if end_time: - query_daytime = query_daytime.filter(DayTimeModel.end_time == end_time) - + query_daytime = query_daytime.filter(DayTimeModel.end_time == end_time) + daytime_queries = [] for row in query: - daytime = query_daytime.filter(DayTimeModel.id == row.daytime_id) - if daytime.first(): - daytime_queries.append(daytime[0]) + daytime = query_daytime.filter(DayTimeModel.id == row.daytime_id) + if daytime.first(): + daytime_queries.append(daytime[0]) return daytime_queries @@ -48,23 +51,24 @@ def resolve_activities(self, info, name=None): for act in self.activities: activity = query.filter(ActivityModel.id == act.id) if activity.first() and (name == act.name or name == None): - activity_queries.append(activity[0]) + activity_queries.append(activity[0]) return activity_queries + @staticmethod - def resolve_capacities(self, info, gym_id = None): - query = Capacity.get_query(info=info) \ - .filter(CapacityModel.gym_id == self.id) \ - .order_by(desc(CapacityModel.updated)) + def resolve_capacities(self, info, gym_id=None): + query = Capacity.get_query(info=info) \ + .filter(CapacityModel.gym_id == self.id) \ + .order_by(desc(CapacityModel.updated)) + + return [query.first()] - return [query.first()] - class DayTime(SQLAlchemyObjectType): - class Meta: - model = DayTimeModel + class Meta: + model = DayTimeModel class GymTime(SQLAlchemyObjectType): - class Meta: - model = GymTimeModel + class Meta: + model = GymTimeModel class Activity(SQLAlchemyObjectType): class Meta: @@ -80,40 +84,124 @@ def resolve_gyms(self, info, name=None): gym = query.filter(GymModel.id == g.id) if gym.first() and (name == g.name or name == None): gym_queries.append(gym[0]) - + return gym_queries + @staticmethod + def resolve_prices(self, info, name=None, cost=None): + query = ActivityPrice.get_query(info=info) + query = query.filter(ActivityPriceModel.activity_id == self.id) + query_price = Price.get_query(info=info) + + if name: + query_price = query_price.filter(PriceModel.name == name) + if cost: + query_price = query_price.filter(PriceModel.cost == cost) + + price_queries = [] + for row in query: + price = query_price.filter(PriceModel.id == row.price_id) + + if price.first(): + price_queries.append(price[0]) + + return price_queries + + class Capacity(SQLAlchemyObjectType): - class Meta: - model = CapacityModel - + class Meta: + model = CapacityModel + class Price(SQLAlchemyObjectType): - class Meta: - model = PriceModel + class Meta: + model = PriceModel + + +class ActivityPrice(SQLAlchemyObjectType): + class Meta: + model = ActivityPriceModel + + +class Facility(SQLAlchemyObjectType): + class Meta: + model = FacilityModel + + @staticmethod + def resolve_times(self, info, day=None, start_time=None, end_time=None): + query = FacilityTime.get_query(info=info) + query = query.filter(FacilityTimeModel.facilty_id == self.id) + query_daytime = DayTime.get_query(info=info) + + if day: + query_datytime = query_daytime.filter(DayTimeModel.day == day) + if start_time: + query_daytime = query_daytime.filter(DayTimeModel.start_time == start_time) + if end_time: + query_daytime = query_daytime.filter(DayTimeModel.end_time == end_time) + + daytime_queries = [] + for row in query: + daytime = query_daytime.filter(DayTimeModel.id == row.daytime_id) + if daytime.first(): + daytime_queries.append(daytime[0]) + + return daytime_queries + + @staticmethod + def resolve_price(self, info, name=None, cost=None): + query = FacilityPrice.get_query(info=info) + query = query.filter(FacilityPriceModel.facility_id == self.id) + query_price = Price.get_query(info=info) + + if name: + query_price = query_price.filter(PriceModel.name == name) + if cost: + query_price = query_price.filter(PriceModel.cost == cost) + + price_queries = [] + for row in query: + price = query_price.filter(PriceModel.id == row.price_id) + + if price.first(): + price_queries.append(price[0]) + + return price_queries + +class FacilityTime(SQLAlchemyObjectType): + class Meta: + model = FacilityTimeModel + +class FacilityPrice(SQLAlchemyObjectType): + class Meta: + model = FacilityPriceModel + +class Equipment(SQLAlchemyObjectType): + class Meta: + model = EquipmentModel class Amenity(SQLAlchemyObjectType): - class Meta: - model = AmenityModel + class Meta: + model = AmenityModel class Query(graphene.ObjectType): - gyms = graphene.List(lambda: Gym, - id=graphene.Int(), - name=graphene.String(), - description=graphene.String(), - location=graphene.String(), - latitude=graphene.Float(), - longitude=graphene.Float(), - image_url=graphene.String()) + gyms = graphene.List(lambda: Gym, + id=graphene.Int(), + name=graphene.String(), + description=graphene.String(), + location=graphene.String(), + latitude=graphene.Float(), + longitude=graphene.Float(), + image_url=graphene.String()) def resolve_gyms(self, info, name=None): - query = Gym.get_query(info) - if name: - query=query.filter(GymModel.name == name) - return query.all() + query = Gym.get_query(info) + if name: + query = query.filter(GymModel.name == name) + return query.all() - activities = graphene.List(lambda: Activity, name=graphene.String( \ + activities = graphene.List(lambda: Activity, name=graphene.String( ), details=graphene.String(), image_url=graphene.String()) def resolve_activities(self, info, name=None): From 639c8c002196dbe189424652509540b56c5d7a5e Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Sat, 15 Apr 2023 16:19:29 -0400 Subject: [PATCH 11/39] Created activity model and many to many relationship with gym model; added activity and gym rresolvers to the schema --- src/app2/models/activity.py | 46 ++++++++++++++++++ src/app2/models/gym.py | 56 ++++++++++++++++++++++ src/app2/schema.py | 96 +++++++++++++++++++++++++++++++++++++ src/test.py | 7 +++ 4 files changed, 205 insertions(+) create mode 100644 src/app2/models/activity.py create mode 100644 src/app2/models/gym.py create mode 100644 src/app2/schema.py create mode 100644 src/test.py diff --git a/src/app2/models/activity.py b/src/app2/models/activity.py new file mode 100644 index 0000000..4a7357e --- /dev/null +++ b/src/app2/models/activity.py @@ -0,0 +1,46 @@ +import datetime +from typing import Counter +from database import Base +from sqlalchemy import Table, Column, Integer, DateTime, ForeignKey, String, Boolean, null +from sqlalchemy.orm import relationship + +activities_to_gyms = Table( + "activities_to_gyms", + Base.metadata, + Column("gym_id", ForeignKey("gym.id"), primary_key=True), + Column("activity_id", ForeignKey("activity.id"), primary_key=True), +) + + +class Activity(Base): + __tablename__ = "activity" + + id = Column(Integer, primary_key=True) + name = Column(String(200), nullable=False) + details = Column(String(1000), nullable=False) + gyms = relationship('Gym', secondary=activities_to_gyms, + back_populates="activities") + #prices - rip + #amenities - rip + image_url = Column(String(1000), nullable=True) + + def __init__(self, **kwargs): + self.name = kwargs.get("name") + self.details = kwargs.get("details") + self.image_url = kwargs.get("image_url") + + +class Price(Base): + __tablename__ = "price" + + id = Column(Integer, primary_key=True) + name = Column(String(100), nullable=False) + cost = Column(Integer, nullable=False) + one_time = Column(Boolean, nullable=False) + image_url = Column(String(1000), nullable=True) + + def __init__(self, **kwargs): + self.name = kwargs.get("name") + self.cost = kwargs.get("cost") + self.one_time = kwargs.get("one_time") + self.image_url = kwargs.get("image_url") diff --git a/src/app2/models/gym.py b/src/app2/models/gym.py new file mode 100644 index 0000000..8eb9749 --- /dev/null +++ b/src/app2/models/gym.py @@ -0,0 +1,56 @@ +import datetime +from database import Base +from sqlalchemy import Column, DateTime, ForeignKey, Integer, String, Boolean, func +from sqlalchemy.orm import backref, relationship +from models.activity import activities_to_gyms + +class Gym(Base): + __tablename__ = "gym" + + id = Column(Integer, primary_key=True) + name = Column(String(100), nullable=False) + description = Column(String(1000), nullable=False) + activities = relationship( + 'Activity', secondary=activities_to_gyms, back_populates="gyms") + #facilties = relation + times = relationship('GymTime', cascade='delete, all') + #capacity = relation + location=Column(String(1000), nullable=False) + image_url = Column(String(1000), nullable=True) + + def __init__(self, **kwargs): + self.name = kwargs.get("name") + self.description = kwargs.get("description") + self.location=kwargs.get("location") + self.image_url = kwargs.get("image_url") + + def serialize(self): + return { + "name": self.name, + "description": self.description, + "times": self.times, + "location": self.location, + "image_url": self.image_url + } + + +class GymTime(Base): + __tablename__ = 'gymtime' + + id = Column(Integer, primary_key=True) + daytime_id = Column(Integer, ForeignKey('daytime.id'), nullable=False) + gym_id = Column(Integer, ForeignKey('gym.id'), nullable=False) + + def __init__(self, **kwargs): + self.daytime_id = kwargs.get("daytime_id") + self.gym_id = kwargs.get("gym_id") + + def serialize(self): + return { + "daytime_id": self.daytime_id, + "gym_id": self.gym_id + } + + + + diff --git a/src/app2/schema.py b/src/app2/schema.py new file mode 100644 index 0000000..fd27361 --- /dev/null +++ b/src/app2/schema.py @@ -0,0 +1,96 @@ +from models.gym import Gym as GymModel, GymTime as GymTimeModel +from models.daytime import DayTime as DayTimeModel +from models.activity import Activity as ActivityModel, Price as PriceModel +import graphene +from graphene import relay +from graphene_sqlalchemy import SQLAlchemyConnectionField, SQLAlchemyObjectType + +class Gym(SQLAlchemyObjectType): + class Meta: + model = GymModel + interfaces = (relay.Node,) + + times = graphene.List(lambda: DayTime, day=graphene.Int(), start_time=graphene.DateTime(), end_time=graphene.DateTime(), restrictions=graphene.String(), special_hours=graphene.Boolean()) + activities = graphene.List(lambda: Activity, name=graphene.String()) + #capacity = graphene.List(lambda: Capacity) + + def resolve_times(self, info, day=None, start_time=None, end_time=None): + query = GymTime.get_query(info=info) + query = query.filter(GymTimeModel.gym_id == self.id) + query_daytime = DayTime.get_query(info=info) #could be wrong + if day: + query_daytime = query_daytime.filter(DayTimeModel.day == day) + if start_time: + query_daytime = query_daytime.filter(DayTimeModel.start_time == start_time) + if end_time: + query_daytime = query_daytime.filter(DayTimeModel.end_time == end_time) + + daytime_queries = [] + for row in query: + daytime = query_daytime.filter(DayTimeModel.id == row.daytime_id) + if daytime.first(): + daytime_queries.append(daytime[0]) + + return daytime_queries + + def resolve_activities(self, info, name=None): + query = Activity.get_query(info=info) + activity_queries = [] + for act in self.activities: + activity = query.filter(ActivityModel.id == act.id) + if activity.first(): + if name and act.name == name: + activity_queries.append(activity[0]) + elif not name: + activity_queries.append(activity[0]) + return activity_queries + +class DayTime(SQLAlchemyObjectType): + class Meta: + model = DayTimeModel + +class GymTime(SQLAlchemyObjectType): + class Meta: + model = GymTimeModel + +class Activity(SQLAlchemyObjectType): + class Meta: + model = ActivityModel + + gyms = graphene.List(lambda: Gym, name=graphene.String()) + + def resolve_gyms(self, info, name=None): + query = Gym.get_query(info=info) + gym_queries = [] + for g in self.gyms: + gym = query.filter(GymModel.id == g.id) + if gym.first(): + if name and g.name == name: + gym_queries.append(gym[0]) + elif not name: + gym_queries.append(gym[0]) + return gym_queries + + +class Query(graphene.ObjectType): + # node = relay.Node.Field() + # allowing single column sorting + + gyms = graphene.List(lambda: Gym, name=graphene.String(), description=graphene.String(), location=graphene.String(),image_url=graphene.String()) + + def resolve_gyms(self, info, name=None): + query = Gym.get_query(info) + if name: + query=query.filter(GymModel.name == name) + return query.all() + + activities = graphene.List(lambda: Activity, name=graphene.String( + ), details=graphene.String(), image_url=graphene.String()) + + def resolve_activities(self, info, name=None): + query = Activity.get_query(info) + if name: + query = query.filter(ActivityModel.name == name) + return query.all() + +schema = graphene.Schema(query=Query) diff --git a/src/test.py b/src/test.py new file mode 100644 index 0000000..9e53272 --- /dev/null +++ b/src/test.py @@ -0,0 +1,7 @@ +from models.activity import Activity, ActivityType +from database import db_session, Base + +def testGym(): + +def testActivity(): + \ No newline at end of file From 75a748df3aad97046dc0d6c4173f11837acd12b9 Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Sat, 15 Apr 2023 16:22:08 -0400 Subject: [PATCH 12/39] added activity model to import statements on init_db() --- src/app2/database.py | 76 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 src/app2/database.py diff --git a/src/app2/database.py b/src/app2/database.py new file mode 100644 index 0000000..1120c70 --- /dev/null +++ b/src/app2/database.py @@ -0,0 +1,76 @@ +from sqlalchemy import create_engine +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import scoped_session, sessionmaker +import datetime + +engine = create_engine("sqlite:///database.sqlite3") +db_session = scoped_session( + sessionmaker(autocommit=False, autoflush=False, bind=engine) +) +Base = declarative_base() +Base.query = db_session.query_property() + +def init_db(): + # import all modules that might define models so they will be registered properly + # on metadata - otherwise import them first before calling init_db() + from models.gym import Gym, GymTime + from models.daytime import DayTime + from models.activity import Activity + + Base.metadata.drop_all(bind=engine) + Base.metadata.create_all(bind=engine) + + Base.metadata.drop_all(bind=engine) + Base.metadata.create_all(bind=engine) + + gym_1 = Gym(name='Helen Newman', description='Something', + location='North', image_url='something') + db_session.add(gym_1) + daytime_1 = DayTime(day=1, start_time=datetime.datetime.utcnow( + ), end_time=datetime.datetime.utcnow(), restrictions='None', special_hours=True) + db_session.add(daytime_1) + db_session.commit() + + gymtime_1 = GymTime(daytime_id=daytime_1.id, gym_id=gym_1.id) + db_session.add(gymtime_1) + db_session.commit() + + activity_1 = Activity( + name='Volleyball', details='It fun', image_url='None') + db_session.add(activity_1) + db_session.commit() + + # adding the gym Helen Newman to the activity Volleyball + activity_1.gyms.append(gym_1) + db_session.add(activity_1) + db_session.commit() + + gym_2 = Gym(name="Morrison", description="Nicer", + location="North", image_url="N/A") + db_session.add(gym_2) + daytime_2 = DayTime(day=2, start_time=datetime.datetime.utcnow( + ), end_time=datetime.datetime.utcnow(), restrictions="A few", special_hours=False) + db_session.add(daytime_2) + db_session.commit() + + gymtime_2 = GymTime(daytime_id=daytime_2.id, gym_id=gym_2.id) + db_session.add(gymtime_2) + db_session.commit() + + activity_2 = Activity(name="Dancing", details="more fun", image_url="No") + db_session.add(activity_2) + db_session.commit() + + activity_2.gyms.append(gym_1) + activity_2.gyms.append(gym_2) + db_session.add(activity_2) + db_session.commit() + + # adding a few capacities + # capacity_1 = Capacity(gym_id=gym_1.id, current=10, + # maximum=70, last_updated=datetime.datetime.utcnow()) + # capacity_2 = Capacity(gym_id=gym_2.id, current=20, + # maximum=100, last_updated=datetime.datetime.utcnow()) + # db_session.add(capacity_1) + # db_session.add(capacity_2) + # db_session.commit() From fbc3a0fe6d6006f197f8f7f9db082ada9f7233ff Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Sat, 15 Apr 2023 16:23:06 -0400 Subject: [PATCH 13/39] deleted testing objects in init_db() --- src/app2/database.py | 52 +------------------------------------------- 1 file changed, 1 insertion(+), 51 deletions(-) diff --git a/src/app2/database.py b/src/app2/database.py index 1120c70..1215b7d 100644 --- a/src/app2/database.py +++ b/src/app2/database.py @@ -23,54 +23,4 @@ def init_db(): Base.metadata.drop_all(bind=engine) Base.metadata.create_all(bind=engine) - gym_1 = Gym(name='Helen Newman', description='Something', - location='North', image_url='something') - db_session.add(gym_1) - daytime_1 = DayTime(day=1, start_time=datetime.datetime.utcnow( - ), end_time=datetime.datetime.utcnow(), restrictions='None', special_hours=True) - db_session.add(daytime_1) - db_session.commit() - - gymtime_1 = GymTime(daytime_id=daytime_1.id, gym_id=gym_1.id) - db_session.add(gymtime_1) - db_session.commit() - - activity_1 = Activity( - name='Volleyball', details='It fun', image_url='None') - db_session.add(activity_1) - db_session.commit() - - # adding the gym Helen Newman to the activity Volleyball - activity_1.gyms.append(gym_1) - db_session.add(activity_1) - db_session.commit() - - gym_2 = Gym(name="Morrison", description="Nicer", - location="North", image_url="N/A") - db_session.add(gym_2) - daytime_2 = DayTime(day=2, start_time=datetime.datetime.utcnow( - ), end_time=datetime.datetime.utcnow(), restrictions="A few", special_hours=False) - db_session.add(daytime_2) - db_session.commit() - - gymtime_2 = GymTime(daytime_id=daytime_2.id, gym_id=gym_2.id) - db_session.add(gymtime_2) - db_session.commit() - - activity_2 = Activity(name="Dancing", details="more fun", image_url="No") - db_session.add(activity_2) - db_session.commit() - - activity_2.gyms.append(gym_1) - activity_2.gyms.append(gym_2) - db_session.add(activity_2) - db_session.commit() - - # adding a few capacities - # capacity_1 = Capacity(gym_id=gym_1.id, current=10, - # maximum=70, last_updated=datetime.datetime.utcnow()) - # capacity_2 = Capacity(gym_id=gym_2.id, current=20, - # maximum=100, last_updated=datetime.datetime.utcnow()) - # db_session.add(capacity_1) - # db_session.add(capacity_2) - # db_session.commit() + From 55913ff25158e20afdab6a2ee89180567bdf438a Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Sat, 15 Apr 2023 16:24:32 -0400 Subject: [PATCH 14/39] deleted duplicate code --- src/app2/database.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/app2/database.py b/src/app2/database.py index 1215b7d..af5a6fc 100644 --- a/src/app2/database.py +++ b/src/app2/database.py @@ -20,7 +20,4 @@ def init_db(): Base.metadata.drop_all(bind=engine) Base.metadata.create_all(bind=engine) - Base.metadata.drop_all(bind=engine) - Base.metadata.create_all(bind=engine) - From 0312ad79f839b1d1ff09d55884d80ba6bd117a72 Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Wed, 19 Apr 2023 19:25:21 -0400 Subject: [PATCH 15/39] Implemented PR edits in activity.py --- src/app2/models/activity.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/app2/models/activity.py b/src/app2/models/activity.py index 4a7357e..470535f 100644 --- a/src/app2/models/activity.py +++ b/src/app2/models/activity.py @@ -16,12 +16,12 @@ class Activity(Base): __tablename__ = "activity" id = Column(Integer, primary_key=True) - name = Column(String(200), nullable=False) + name = Column(String(), nullable=False) details = Column(String(1000), nullable=False) gyms = relationship('Gym', secondary=activities_to_gyms, back_populates="activities") - #prices - rip - #amenities - rip + prices = relationship('Price', cascade='delete, all') + amenities = relationship('Amenity', cascade='delete, all') image_url = Column(String(1000), nullable=True) def __init__(self, **kwargs): @@ -38,9 +38,25 @@ class Price(Base): cost = Column(Integer, nullable=False) one_time = Column(Boolean, nullable=False) image_url = Column(String(1000), nullable=True) + activity_id = Column(Integer, ForeignKey('activity.id'), nullable=False) def __init__(self, **kwargs): self.name = kwargs.get("name") self.cost = kwargs.get("cost") self.one_time = kwargs.get("one_time") self.image_url = kwargs.get("image_url") + self.activity_id = kwargs.get("activity_id") + + +class Amenity(Base): + __tablename__ = 'amenity' + + id = Column(Integer, primary_key=True) + name = Column(String(), nullable=False) + image_url = Column(String(), nullable=True) + activity_id = Column(Integer, ForeignKey('activity.id'), nullable=False) + + def __init__(self, **kwargs): + self.name = kwargs.get("name") + self.image_url = kwargs.get("image_url") + self.activity_id = kwargs.get("activity_id") From 2de324e8970d5bce787eb6a7c44f92462504a98d Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Wed, 19 Apr 2023 19:26:09 -0400 Subject: [PATCH 16/39] Implemented PR edits in gym.py --- src/app2/models/gym.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/app2/models/gym.py b/src/app2/models/gym.py index 8eb9749..51b2466 100644 --- a/src/app2/models/gym.py +++ b/src/app2/models/gym.py @@ -12,9 +12,7 @@ class Gym(Base): description = Column(String(1000), nullable=False) activities = relationship( 'Activity', secondary=activities_to_gyms, back_populates="gyms") - #facilties = relation times = relationship('GymTime', cascade='delete, all') - #capacity = relation location=Column(String(1000), nullable=False) image_url = Column(String(1000), nullable=True) From 90a8334465ebe628fabd29088301aa6a260f9457 Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Wed, 19 Apr 2023 19:27:10 -0400 Subject: [PATCH 17/39] Implemented PR changes in schema.py and added Price and Amenity class and price resolver in Activity class --- src/app2/schema.py | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/app2/schema.py b/src/app2/schema.py index fd27361..62f0bbe 100644 --- a/src/app2/schema.py +++ b/src/app2/schema.py @@ -1,6 +1,7 @@ from models.gym import Gym as GymModel, GymTime as GymTimeModel from models.daytime import DayTime as DayTimeModel from models.activity import Activity as ActivityModel, Price as PriceModel +from models.activity import Amenity as AmenityModel import graphene from graphene import relay from graphene_sqlalchemy import SQLAlchemyConnectionField, SQLAlchemyObjectType @@ -8,11 +9,9 @@ class Gym(SQLAlchemyObjectType): class Meta: model = GymModel - interfaces = (relay.Node,) times = graphene.List(lambda: DayTime, day=graphene.Int(), start_time=graphene.DateTime(), end_time=graphene.DateTime(), restrictions=graphene.String(), special_hours=graphene.Boolean()) activities = graphene.List(lambda: Activity, name=graphene.String()) - #capacity = graphene.List(lambda: Capacity) def resolve_times(self, info, day=None, start_time=None, end_time=None): query = GymTime.get_query(info=info) @@ -38,10 +37,7 @@ def resolve_activities(self, info, name=None): activity_queries = [] for act in self.activities: activity = query.filter(ActivityModel.id == act.id) - if activity.first(): - if name and act.name == name: - activity_queries.append(activity[0]) - elif not name: + if activity.first() and (name == act.name or name == None): activity_queries.append(activity[0]) return activity_queries @@ -58,23 +54,37 @@ class Meta: model = ActivityModel gyms = graphene.List(lambda: Gym, name=graphene.String()) + prices = graphene.List(lambda: Price, cost=graphene.Int(), one_time=graphene.Boolean()) def resolve_gyms(self, info, name=None): query = Gym.get_query(info=info) gym_queries = [] for g in self.gyms: gym = query.filter(GymModel.id == g.id) - if gym.first(): - if name and g.name == name: - gym_queries.append(gym[0]) - elif not name: - gym_queries.append(gym[0]) + if gym.first() and (name == g.name or name == None): + gym_queries.append(gym[0]) + return gym_queries + def resolve_prices(self, info, cost=None, one_time=None): + query = Price.get_query(info=info) + query = query.filter(PriceModel.activity_id == self.id) + if cost: + query = query.filter(PriceModel.cost == cost) + if one_time != None: + query = query.filter(PriceModel.one_time == one_time) + return query + +class Price(SQLAlchemyObjectType): + class Meta: + model = PriceModel + +class Amenity(SQLAlchemyObjectType): + class Meta: + model = AmenityModel + class Query(graphene.ObjectType): - # node = relay.Node.Field() - # allowing single column sorting gyms = graphene.List(lambda: Gym, name=graphene.String(), description=graphene.String(), location=graphene.String(),image_url=graphene.String()) @@ -84,8 +94,8 @@ def resolve_gyms(self, info, name=None): query=query.filter(GymModel.name == name) return query.all() - activities = graphene.List(lambda: Activity, name=graphene.String( - ), details=graphene.String(), image_url=graphene.String()) + activities = graphene.List(lambda: Activity, name=graphene.String( \ + ), details=graphene.String(), image_url=graphene.String()) def resolve_activities(self, info, name=None): query = Activity.get_query(info) From 1726494880c02228c0650f7106ea0de23bb9446e Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Thu, 20 Apr 2023 12:12:26 -0400 Subject: [PATCH 18/39] Populated models to test --- src/app2/database.py | 66 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/src/app2/database.py b/src/app2/database.py index af5a6fc..6b7befa 100644 --- a/src/app2/database.py +++ b/src/app2/database.py @@ -15,9 +15,73 @@ def init_db(): # on metadata - otherwise import them first before calling init_db() from models.gym import Gym, GymTime from models.daytime import DayTime - from models.activity import Activity + from models.activity import Activity, Price, Amenity Base.metadata.drop_all(bind=engine) Base.metadata.create_all(bind=engine) + gym_1 = Gym(name='Helen Newman', description='Something', + location='North', image_url='something') + db_session.add(gym_1) + daytime_1 = DayTime(day=1, start_time=datetime.datetime.utcnow( + ), end_time=datetime.datetime.utcnow(), restrictions='None', special_hours=True) + db_session.add(daytime_1) + db_session.commit() + + gymtime_1 = GymTime(daytime_id=daytime_1.id, gym_id=gym_1.id) + db_session.add(gymtime_1) + db_session.commit() + + activity_1 = Activity( + name='Volleyball', details='It fun', image_url='None') + db_session.add(activity_1) + db_session.commit() + + # adding the gym Helen Newman to the activity Volleyball + activity_1.gyms.append(gym_1) + db_session.add(activity_1) + db_session.commit() + + price_1 = Price(name="price1", cost=20, one_time=False, image_url="none", activity_id=activity_1.id) + db_session.add(price_1) + db_session.commit() + activity_1.prices.append(price_1) + db_session.add(activity_1) + db_session.commit() + + price_2 = Price(name="price2", cost=40, one_time=True, image_url="n/a", activity_id = activity_1.id) + db_session.add(price_2) + db_session.commit() + activity_1.prices.append(price_2) + db_session.add(activity_1) + db_session.commit() + + amenity_1 = Amenity(name="locker", image_url="none", activity_id=activity_1.id) + db_session.add(amenity_1) + db_session.commit() + activity_1.amenities.append(amenity_1) + db_session.add(activity_1) + db_session.commit() + + gym_2 = Gym(name="Morrison", description="Nicer", + location="North", image_url="N/A") + db_session.add(gym_2) + daytime_2 = DayTime(day=2, start_time=datetime.datetime.utcnow( + ), end_time=datetime.datetime.utcnow(), restrictions="A few", special_hours=False) + db_session.add(daytime_2) + db_session.commit() + + gymtime_2 = GymTime(daytime_id=daytime_2.id, gym_id=gym_2.id) + db_session.add(gymtime_2) + db_session.commit() + + activity_2 = Activity(name="Dancing", details="more fun", image_url="No") + db_session.add(activity_2) + db_session.commit() + + activity_2.gyms.append(gym_1) + activity_2.gyms.append(gym_2) + db_session.add(activity_2) + db_session.commit() + From 305753a269ae1bce1da4e0efe7b39dd490a7324e Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Sun, 30 Apr 2023 22:15:11 -0400 Subject: [PATCH 19/39] Cleaning up some merge conflicts --- src/app2/models/gym.py | 54 --------------------- src/app2/schema.py | 106 ----------------------------------------- src/uplift/database.py | 96 +++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 160 deletions(-) create mode 100644 src/uplift/database.py diff --git a/src/app2/models/gym.py b/src/app2/models/gym.py index 51b2466..e69de29 100644 --- a/src/app2/models/gym.py +++ b/src/app2/models/gym.py @@ -1,54 +0,0 @@ -import datetime -from database import Base -from sqlalchemy import Column, DateTime, ForeignKey, Integer, String, Boolean, func -from sqlalchemy.orm import backref, relationship -from models.activity import activities_to_gyms - -class Gym(Base): - __tablename__ = "gym" - - id = Column(Integer, primary_key=True) - name = Column(String(100), nullable=False) - description = Column(String(1000), nullable=False) - activities = relationship( - 'Activity', secondary=activities_to_gyms, back_populates="gyms") - times = relationship('GymTime', cascade='delete, all') - location=Column(String(1000), nullable=False) - image_url = Column(String(1000), nullable=True) - - def __init__(self, **kwargs): - self.name = kwargs.get("name") - self.description = kwargs.get("description") - self.location=kwargs.get("location") - self.image_url = kwargs.get("image_url") - - def serialize(self): - return { - "name": self.name, - "description": self.description, - "times": self.times, - "location": self.location, - "image_url": self.image_url - } - - -class GymTime(Base): - __tablename__ = 'gymtime' - - id = Column(Integer, primary_key=True) - daytime_id = Column(Integer, ForeignKey('daytime.id'), nullable=False) - gym_id = Column(Integer, ForeignKey('gym.id'), nullable=False) - - def __init__(self, **kwargs): - self.daytime_id = kwargs.get("daytime_id") - self.gym_id = kwargs.get("gym_id") - - def serialize(self): - return { - "daytime_id": self.daytime_id, - "gym_id": self.gym_id - } - - - - diff --git a/src/app2/schema.py b/src/app2/schema.py index 62f0bbe..e69de29 100644 --- a/src/app2/schema.py +++ b/src/app2/schema.py @@ -1,106 +0,0 @@ -from models.gym import Gym as GymModel, GymTime as GymTimeModel -from models.daytime import DayTime as DayTimeModel -from models.activity import Activity as ActivityModel, Price as PriceModel -from models.activity import Amenity as AmenityModel -import graphene -from graphene import relay -from graphene_sqlalchemy import SQLAlchemyConnectionField, SQLAlchemyObjectType - -class Gym(SQLAlchemyObjectType): - class Meta: - model = GymModel - - times = graphene.List(lambda: DayTime, day=graphene.Int(), start_time=graphene.DateTime(), end_time=graphene.DateTime(), restrictions=graphene.String(), special_hours=graphene.Boolean()) - activities = graphene.List(lambda: Activity, name=graphene.String()) - - def resolve_times(self, info, day=None, start_time=None, end_time=None): - query = GymTime.get_query(info=info) - query = query.filter(GymTimeModel.gym_id == self.id) - query_daytime = DayTime.get_query(info=info) #could be wrong - if day: - query_daytime = query_daytime.filter(DayTimeModel.day == day) - if start_time: - query_daytime = query_daytime.filter(DayTimeModel.start_time == start_time) - if end_time: - query_daytime = query_daytime.filter(DayTimeModel.end_time == end_time) - - daytime_queries = [] - for row in query: - daytime = query_daytime.filter(DayTimeModel.id == row.daytime_id) - if daytime.first(): - daytime_queries.append(daytime[0]) - - return daytime_queries - - def resolve_activities(self, info, name=None): - query = Activity.get_query(info=info) - activity_queries = [] - for act in self.activities: - activity = query.filter(ActivityModel.id == act.id) - if activity.first() and (name == act.name or name == None): - activity_queries.append(activity[0]) - return activity_queries - -class DayTime(SQLAlchemyObjectType): - class Meta: - model = DayTimeModel - -class GymTime(SQLAlchemyObjectType): - class Meta: - model = GymTimeModel - -class Activity(SQLAlchemyObjectType): - class Meta: - model = ActivityModel - - gyms = graphene.List(lambda: Gym, name=graphene.String()) - prices = graphene.List(lambda: Price, cost=graphene.Int(), one_time=graphene.Boolean()) - - def resolve_gyms(self, info, name=None): - query = Gym.get_query(info=info) - gym_queries = [] - for g in self.gyms: - gym = query.filter(GymModel.id == g.id) - if gym.first() and (name == g.name or name == None): - gym_queries.append(gym[0]) - - return gym_queries - - def resolve_prices(self, info, cost=None, one_time=None): - query = Price.get_query(info=info) - query = query.filter(PriceModel.activity_id == self.id) - if cost: - query = query.filter(PriceModel.cost == cost) - if one_time != None: - query = query.filter(PriceModel.one_time == one_time) - return query - -class Price(SQLAlchemyObjectType): - class Meta: - model = PriceModel - -class Amenity(SQLAlchemyObjectType): - class Meta: - model = AmenityModel - - -class Query(graphene.ObjectType): - - gyms = graphene.List(lambda: Gym, name=graphene.String(), description=graphene.String(), location=graphene.String(),image_url=graphene.String()) - - def resolve_gyms(self, info, name=None): - query = Gym.get_query(info) - if name: - query=query.filter(GymModel.name == name) - return query.all() - - activities = graphene.List(lambda: Activity, name=graphene.String( \ - ), details=graphene.String(), image_url=graphene.String()) - - def resolve_activities(self, info, name=None): - query = Activity.get_query(info) - if name: - query = query.filter(ActivityModel.name == name) - return query.all() - -schema = graphene.Schema(query=Query) diff --git a/src/uplift/database.py b/src/uplift/database.py new file mode 100644 index 0000000..511c6e3 --- /dev/null +++ b/src/uplift/database.py @@ -0,0 +1,96 @@ +from sqlalchemy import create_engine +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import scoped_session, sessionmaker +import datetime + +ASSET_BASE_URL = "https://raw.githubusercontent.com/cuappdev/assets/master/uplift/" + +engine = create_engine("sqlite:///database.sqlite3") +db_session = scoped_session( + sessionmaker(autocommit=False, autoflush=False, bind=engine) +) +Base = declarative_base() +Base.query = db_session.query_property() + +def init_db(): + """ + Initialize database for uplift. + """ + # import all modules that might define models so they will be registered properly + # on metadata - otherwise import them first before calling init_db() + Base.metadata.create_all(bind=engine) + create_gym_table() + + +""" +Initialize basic information for all five fitness centers +(Helen Newman...Teagle Down) with location, hours, images. +""" +def create_gym_table(): + # import all modules that might define models so they will be registered properly + # on metadata - otherwise import them first before calling init_db() + from models.gym import Gym, GymTime + from models.daytime import DayTime + from models.capacity import Capacity + + helen_newman = Gym( + id=1, + name='Helen Newman', + description='description', + location='123 Cradit Farm Road', + latitude=42.454342, + longitude=-76.473618, + image_url=ASSET_BASE_URL + 'gyms/helen-newman.jpg' + ) + + toni_morrison = Gym( + id=2, + name = 'Toni Morrison', + description='description', + location='18 Sisson Place', + latitude=0.00, + longitude=0.00, + image_url = ASSET_BASE_URL + 'gyms/toni-morrison-outside-min.jpeg' + ) + + noyes = Gym( + id=3, + name='Noyes', + description='description', + location='306 West Avenue', + latitude=0.0, + longitude=0.0, + image_url=ASSET_BASE_URL + 'gyms/noyes.jpg' + ) + + teagle_up = Gym( + id=4, + name='Teagle Up', + description='description', + location='512 Campus Road', + latitude=0.0, + longitude=0.0, + image_url=ASSET_BASE_URL + 'gyms/teagle.jpg' + ) + + teagle_down = Gym( + id=5, + name='Teagle Down', + description='description', + location='512 Campus Road', + latitude=0.0, + longitude=0.0, + image_url=ASSET_BASE_URL + 'gyms/teagle.jpg' + ) + + gyms = [ + helen_newman, + noyes, + # morrison, + teagle_up, + teagle_down + ] + + for gym in gyms: + db_session.merge(gym) + From 4159a01d3e7a2a89bf965f0f7578ddfdcef374ac Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Mon, 28 Aug 2023 17:43:25 -0400 Subject: [PATCH 20/39] almost implementing Facilities --- src/app2/database.py | 3 + src/app2/database.py.orig | 91 +++++++++++++++ src/app2/database.sqlite3 | Bin 0 -> 36864 bytes src/appdev-py | 1 + src/models/facility.py | 102 +++++++++++++++-- src/models/price.py | 20 ++++ src/uplift/database.py | 140 +++++++++++++++++++++++- src/uplift/database.sqlite3 | Bin 0 -> 40960 bytes src/uplift/models/gym.py | 49 +++++++++ src/uplift/schema.py | 213 ++++++++++++++++++++++++++++++++++++ 10 files changed, 609 insertions(+), 10 deletions(-) create mode 100644 src/app2/database.py.orig create mode 100644 src/app2/database.sqlite3 create mode 160000 src/appdev-py create mode 100644 src/models/price.py create mode 100644 src/uplift/database.sqlite3 create mode 100644 src/uplift/models/gym.py create mode 100644 src/uplift/schema.py diff --git a/src/app2/database.py b/src/app2/database.py index 6b7befa..a676da0 100644 --- a/src/app2/database.py +++ b/src/app2/database.py @@ -84,4 +84,7 @@ def init_db(): db_session.add(activity_2) db_session.commit() + + + diff --git a/src/app2/database.py.orig b/src/app2/database.py.orig new file mode 100644 index 0000000..a5831ee --- /dev/null +++ b/src/app2/database.py.orig @@ -0,0 +1,91 @@ +from sqlalchemy import create_engine +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import scoped_session, sessionmaker +import datetime + +engine = create_engine("sqlite:///database.sqlite3") +db_session = scoped_session( + sessionmaker(autocommit=False, autoflush=False, bind=engine) +) +Base = declarative_base() +Base.query = db_session.query_property() + +def init_db(): + # import all modules that might define models so they will be registered properly + # on metadata - otherwise import them first before calling init_db() + from models.gym import Gym, GymTime + from models.daytime import DayTime + from models.activity import Activity, Price, Amenity + + Base.metadata.drop_all(bind=engine) + Base.metadata.create_all(bind=engine) + + gym_1 = Gym(name='Helen Newman', description='Something', + location='North', image_url='something') + db_session.add(gym_1) + daytime_1 = DayTime(day=1, start_time=datetime.datetime.utcnow( + ), end_time=datetime.datetime.utcnow(), restrictions='None', special_hours=True) + db_session.add(daytime_1) + db_session.commit() + + gymtime_1 = GymTime(daytime_id=daytime_1.id, gym_id=gym_1.id) + db_session.add(gymtime_1) + db_session.commit() + + activity_1 = Activity( + name='Volleyball', details='It fun', image_url='None') + db_session.add(activity_1) + db_session.commit() + + # adding the gym Helen Newman to the activity Volleyball + activity_1.gyms.append(gym_1) + db_session.add(activity_1) + db_session.commit() + + price_1 = Price(name="price1", cost=20, one_time=False, image_url="none", activity_id=activity_1.id) + db_session.add(price_1) + db_session.commit() + activity_1.prices.append(price_1) + db_session.add(activity_1) + db_session.commit() + + price_2 = Price(name="price2", cost=40, one_time=True, image_url="n/a", activity_id = activity_1.id) + db_session.add(price_2) + db_session.commit() + activity_1.prices.append(price_2) + db_session.add(activity_1) + db_session.commit() + + amenity_1 = Amenity(name="locker", image_url="none", activity_id=activity_1.id) + db_session.add(amenity_1) + db_session.commit() + activity_1.amenities.append(amenity_1) + db_session.add(activity_1) + db_session.commit() + + gym_2 = Gym(name="Morrison", description="Nicer", + location="North", image_url="N/A") + db_session.add(gym_2) + daytime_2 = DayTime(day=2, start_time=datetime.datetime.utcnow( + ), end_time=datetime.datetime.utcnow(), restrictions="A few", special_hours=False) + db_session.add(daytime_2) + db_session.commit() + + gymtime_2 = GymTime(daytime_id=daytime_2.id, gym_id=gym_2.id) + db_session.add(gymtime_2) + db_session.commit() + + activity_2 = Activity(name="Dancing", details="more fun", image_url="No") + db_session.add(activity_2) + db_session.commit() + + activity_2.gyms.append(gym_1) + activity_2.gyms.append(gym_2) + db_session.add(activity_2) + db_session.commit() + +def merge(): + pass + + + diff --git a/src/app2/database.sqlite3 b/src/app2/database.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..515f80ebcd7abd62e216633e0a5994606f941598 GIT binary patch literal 36864 zcmeI*?QhdY90%|_Cr#p_;6ayJRaJ3&F)0xR@<3TZnwSZOMzjt~J0`Rjkx5Kz&9OV% z9jnwgwER)L+WvyQ+zX_=JoGTs?M^=-pD?c~#hTw(_`}kHRj6Ve13K zHvPSLRY-*$S567r=3Ur5rPEwh(jMkO-!i(pu9dU~Vd*{J{D!~Tzoi)3J{4S2A4hnw zlFQ4oOrNyF2zOkwXM~GhDWrYB{sCtNTgApRFJ%C>^K?T&G6Vt>f?NB&gA4TYLu9E z-}u)1+Txc+U47Sg!q?rn^N>-uHd>eCvsfXR$qq`HaQHo;VRFX9I9_E_mM@3+v{`2? zn&<1TA7$Z9K8tO(*40!R8g_q5t7~{ZA2Yt`*j_SxkMh*pF?yzMb+?^e*BhJUsZ$ou zXmO^dH$F;NJ}q^GygWBY4^JhtF+XdWlt*|PCt3_oMWe&DZ+Jb|+zDbzhm>-$oSyy< zU8aoSSL5bEEz`WbxJVB^iRRjP{!8*pNQIZwzUGvaI`F>X>!$U}*-G_zqvI~}L=~hT zi1eH4uD5N622;+dPe-81d2f#dRj?C;u|Gf!v8 zhx4U-j%68p4|L0F`B8&yMA!dMiS(oN^z9E2M+gB3KmY;|fB*y_009U<00Iy=Spo|} zjx5UZ+`8ksrsvoizw^n}9M|90E-4k7BOjfU&#fAkVKdEmG|=r0XJGi-{9}Qzlb5`T zuK)Lm^u4ryvIG$=1Rwwb2tWV=5P$##AOHafK;ZuoP=q|8iXs<;dbQrTP`!MieudTR z*BV!^RWDz>^6_%Lwlb-u-cZ;>DLo=c{%VWw&FM{j;-}njz z0uX=z1Rwwb2tWV=5P$##AOL}5E|AaC;Oak<%ZlNr09jEKqx=7#5$T2W?3jm#!-oI_ zAOHafKmY;|fB*y_009V`Jb^R(%LVgPoD;(zKdG1POZr*oh(J!rlJNF_nkAz6H{@J=*8l(j literal 0 HcmV?d00001 diff --git a/src/appdev-py b/src/appdev-py new file mode 160000 index 0000000..fffe58a --- /dev/null +++ b/src/appdev-py @@ -0,0 +1 @@ +Subproject commit fffe58a01ba5bc00493213e2baa00a6a9e393280 diff --git a/src/models/facility.py b/src/models/facility.py index c53dece..96599b0 100644 --- a/src/models/facility.py +++ b/src/models/facility.py @@ -1,5 +1,14 @@ +<<<<<<< HEAD:src/models/facility.py +<<<<<<<< HEAD:src/models/facility.py import enum from sqlalchemy import Column, ForeignKey, String, Enum, Integer +======== +import datetime +from importlib.machinery import FrozenImporter +from typing import Counter +from database import Base +from sqlalchemy import Table, Column, Integer, DateTime, ForeignKey, String, Boolean, null +>>>>>>>> 2eebca9 (almost implementing Facilities):src/uplift/models/activity.py from sqlalchemy.orm import relationship from src.database import Base from src.models.openhours import OpenHours @@ -16,6 +25,7 @@ class Facility(Base): id = Column(Integer, primary_key=True) gym_id = Column(Integer, ForeignKey("gym.id"), nullable=False) name = Column(String(), nullable=False) +<<<<<<<< HEAD:src/models/facility.py facility_type = Column(Enum(FacilityType), nullable=False) open_hours = relationship("OpenHours") capacities = relationship("Capacity") @@ -24,6 +34,14 @@ class Facility(Base): # prices = relationship('Price', cascade='delete, all') # amenities = relationship('Amenity', cascade='delete, all') # image_url = Column(String(1000), nullable=True) +======== + details = Column(String(), nullable=False) + gyms = relationship('Gym', secondary=activities_to_gyms, + back_populates="activities") + prices = relationship('ActivityPrice', cascade='delete, all') + amenities = relationship('Amenity', cascade='delete, all') + image_url = Column(String(), nullable=True) +>>>>>>>> 2eebca9 (almost implementing Facilities):src/uplift/models/activity.py def __init__(self, **kwargs): self.id = kwargs.get("id") @@ -43,27 +61,25 @@ def serialize(self): "capacities": self.capacities, } +<<<<<<<< HEAD:src/models/facility.py # Left here as a reference for the above TODOs """ class Price(Base): __tablename__ = "price" +======== +class ActivityPrice(Base): + __tablename__ = "activityprice" +>>>>>>>> 2eebca9 (almost implementing Facilities):src/uplift/models/activity.py id = Column(Integer, primary_key=True) - name = Column(String(100), nullable=False) - cost = Column(Integer, nullable=False) - one_time = Column(Boolean, nullable=False) - image_url = Column(String(1000), nullable=True) activity_id = Column(Integer, ForeignKey('activity.id'), nullable=False) + price_id = Column(Integer, ForeignKey('price.id'), nullable=False) def __init__(self, **kwargs): - self.name = kwargs.get("name") - self.cost = kwargs.get("cost") - self.one_time = kwargs.get("one_time") - self.image_url = kwargs.get("image_url") self.activity_id = kwargs.get("activity_id") - + self.price = kwargs.get("price_id") class Amenity(Base): __tablename__ = 'amenity' @@ -78,3 +94,71 @@ def __init__(self, **kwargs): self.image_url = kwargs.get("image_url") self.activity_id = kwargs.get("activity_id") """ +======= +from ast import For +from database import Base +from sqlalchemy import Column, DateTime, ForeignKey, Integer, Float, String, func +from sqlalchemy.orm import backref, relationship +from models.price import Price + + +class Facility(Base): + __tablename__ = "facility" + + id = Column(Integer, primary_key=True) + name = Column(String(), nullable=False) + times = relationship('FacilityTime', cascade='delete, all') + price = relationship('Price', cascade='delete, all') + equipment = relationship('Equipment', cascade='delete, all') + image_url = Column(String(), nullable=True) + + def __init__(self, **kwargs): + self.name = kwargs.get("name") + self.image_url = kwargs.get("image") + + +class FacilityTime(Base): + __tablename__ = "facilitytime" + + id = Column(Integer, primary_key=True) + facilty_id = Column(Integer, ForeignKey('facility.id'), nullable=False) + daytime_id = Column(Integer, ForeignKey('daytime.id'), nullable=False) + + def __init__(self, **kwargs): + self.facility_id = kwargs.get("facility_id") + self.daytime_id = kwargs.get("daytime_id") + +class FacilityPrice(Base): + __tablename__ = "facilityprice" + + id = Column(Integer, primary_key=True) + facility_id = Column(Integer, ForeignKey('facility.id'), nullable=False) + price_id = Column(Integer, ForeignKey('price.id'), nullable=False) + + def __init__(self, **kwargs): + self.facility_id=kwargs.get("facility_id") + self.price_id=kwargs.get("price_id") + + +class Equipment(Base): + __tablename__ = "equipment" + + id = Column(Integer, primary_key=True) + equipment_type = Column(String(), nullable=False) + name = Column(String(), nullable=False) + quantity = Column(Integer, nullable=False) + facility_id = Column(Integer, ForeignKey('facility.id'), nullable=False) + + def __init__(self, **kwargs): + self.equipment_type = kwargs.get("equipment_type") + self.name = kwargs.get("name") + self.quantity = kwargs.get("quantity") + self.facility_id=kwargs.get("facility_id") + + + + + + + +>>>>>>> 2eebca9 (almost implementing Facilities):src/uplift/models/facility.py diff --git a/src/models/price.py b/src/models/price.py new file mode 100644 index 0000000..3f35a61 --- /dev/null +++ b/src/models/price.py @@ -0,0 +1,20 @@ +from database import Base +from sqlalchemy import Column, String, Integer, ForeignKey, Boolean +from sqlalchemy.orm import relationship + +class Price(Base): + __tablename__ = "price" + + id = Column(Integer, primary_key=True) + name = Column(String(), nullable=False) + cost = Column(Integer, nullable=False) + one_time = Column(Boolean, nullable=False) + activity_id = Column(Integer, ForeignKey('activity.id'), nullable=False) + + def __init__(self, **kwargs): + self.id = kwargs.get('id') + self.name = kwargs.get("name") + self.cost = kwargs.get("cost") + self.one_time = kwargs.get("one_time") + self.activity_id = kwargs.get('activity_id') + diff --git a/src/uplift/database.py b/src/uplift/database.py index 511c6e3..ab905d4 100644 --- a/src/uplift/database.py +++ b/src/uplift/database.py @@ -19,7 +19,119 @@ def init_db(): # import all modules that might define models so they will be registered properly # on metadata - otherwise import them first before calling init_db() Base.metadata.create_all(bind=engine) - create_gym_table() + def init_db(): + # import all modules that might define models so they will be registered properly + # on metadata - otherwise import them first before calling init_db() + from models.gym import Gym, GymTime + from models.daytime import DayTime + from models.activity import Activity, Amenity, ActivityPrice + from models.price import Price + from models.facility import Facility, FacilityTime, Equipment, FacilityPrice + + Base.metadata.drop_all(bind=engine) + Base.metadata.create_all(bind=engine) + + gym_1 = Gym(name='Helen Newman', description='Something', + location='North', image_url='something') + db_session.add(gym_1) + daytime_1 = DayTime(day=1, start_time=datetime.datetime.utcnow( + ), end_time=datetime.datetime.utcnow(), restrictions='None', special_hours=True) + db_session.add(daytime_1) + db_session.commit() + + gymtime_1 = GymTime(daytime_id=daytime_1.id, gym_id=gym_1.id) + db_session.add(gymtime_1) + db_session.commit() + + activity_1 = Activity( + name='Volleyball', details='It fun', image_url='None') + db_session.add(activity_1) + db_session.commit() + + # adding the gym Helen Newman to the activity Volleyball + activity_1.gyms.append(gym_1) + db_session.add(activity_1) + db_session.commit() + + price_1 = Price(name="price1", cost=20, one_time=False, image_url="none") + db_session.add(price_1) + db_session.commit() + + price_2 = Price(name="price2", cost=40, one_time=True, image_url="n/a") + db_session.add(price_2) + db_session.commit() + + price_3=Price(name="price3", cost=50, one_time=False, image_url="none") + price_4=Price(name="price4", cost=15, one_time=False, image_url="n/a") + db_session.add(price_3) + db_session.add(price_4) + db_session.commit() + + activityprice_1 = ActivityPrice(activity_id=activity_1.id, price_id=price_1.id) + activityprice_2=ActivityPrice(activity_id=activity_1.id, price_id=price_2.id) + db_session.add(activityprice_1) + db_session.add(activityprice_2) + db_session.commit() + + + amenity_1 = Amenity(name="locker", image_url="none", activity_id=activity_1.id) + db_session.add(amenity_1) + db_session.commit() + activity_1.amenities.append(amenity_1) + db_session.add(activity_1) + db_session.commit() + + facility_1 = Facility(name="basketball court", image_url="None") + db_session.add(facility_1) + db_session.commit() + + facility_2 = Facility(name="beach volleyball court", image_url="N/A") + db_session.add(facility_2) + db_session.commit() + + facilitytime_1 = FacilityTime(facility_id=facility_1.id, daytime_id=daytime_1.id) + db_session.add(facilitytime_1) + db_session.commit() + + facilityprice_1 = FacilityPrice(facility_id=facility_1.id, price_id=price_3.id) + facilityprice_2 = FacilityPrice(facility_id=facility_1.id, price_id=price_4.id) + db_session.add(facilityprice_1) + db_session.add(facilityprice_2) + db_session.commit() + + equipment_1 = Equipment(equipment_type="Exercise machine", name="Squat Rack 1", quantity=2, facility_id=facility_1.id, image_url="n/a") + db_session.add(equipment_1) + db_session.commit() + + equipment_2 = Equipment(equipment_type="Exercise thingy", name="Dumbbell", quantity=20, facility_id=facility_1.id, image_url="none") + db_session.add(equipment_2) + db_session.commit() + + gym_2 = Gym(name="Morrison", description="Nicer", + location="North", image_url="N/A") + db_session.add(gym_2) + daytime_2 = DayTime(day=2, start_time=datetime.datetime.utcnow( + ), end_time=datetime.datetime.utcnow(), restrictions="A few", special_hours=False) + db_session.add(daytime_2) + db_session.commit() + + facilitytime_2 = FacilityTime(facility_id=facility_2.id, daytime_id=daytime_2.id) + db_session.add(facilitytime_2) + db_session.commit() + + gymtime_2 = GymTime(daytime_id=daytime_2.id, gym_id=gym_2.id) + db_session.add(gymtime_2) + db_session.commit() + + activity_2 = Activity(name="Dancing", details="more fun", image_url="No") + db_session.add(activity_2) + db_session.commit() + + activity_2.gyms.append(gym_1) + activity_2.gyms.append(gym_2) + db_session.add(activity_2) + db_session.commit() + """ @@ -94,3 +206,29 @@ def create_gym_table(): for gym in gyms: db_session.merge(gym) +def create_activities_table(): + from models.activity import Activity, Amenity + from models.daytime import DayTime + + basketball = Activity(name = "Basketball", + details="details", + image_url="None" + ) + + beach_volleyball = Activity( + name="Beach Volleyball", + details="details", + image_url="N/A" + ) + + activities = [ + basketball, + beach_volleyball + ] + + for act in activities: + db_session.merge(act) + + + + diff --git a/src/uplift/database.sqlite3 b/src/uplift/database.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..b9e861547174b89d3e45b9e1b074e22e3e8a3ca9 GIT binary patch literal 40960 zcmeI*&u`mg7zc2>Ntz#BlCfzDsOt8X3a!!F#!i-QL;{v&E~}O$Bh5B#LW;cjU2Bxs zA$B?{m_*k71)Sg?;L3>;7r1fZJc$D!ahs5kIC6p4c7E7Rnr$pd)%3NLC4KYweV^y! z*RShF%C$M>NrpSl@jQ2l5RT*K*(1Up{Vl{^`1?PwXWsStu$S}PTKTi+ z+!Zby{E3VG75(|x@5lUe#qiU}KcR0}6E+Ay00Izz00drEpj!(E6Z7-@{wY(w*PwEf zYO1-{dx{h)QobsYYW{LjBE3ek90{um*(_D1_oWIcm8+z5vshdqk+8->$gO;(a5e9J zLv702wAN`i`tMrNa@|yS*SzA=jikWLZ^`);=5MinRHD$!c46?VltS zX+x?=rGm6Y`t9~kk>sO`pSg;H27x5xEg{xBG8d)9;xmhC1!U_?S|C#Q@Y%n2;{Juli z%Sok1&D3k#drf1sCFnsNecuvhdmdKS3zhBkvobi~tkaQ7ofyyjU`;PGp9;a*#BGu1 zR866u7#}y-@4_{?W9s(Lwb6=e;%J-od$IN4y4gT5v9Q2DddE5adZ$F6VRoG6-gC}U z&s0;WDXR^mfBrcW%@Z+UG9Ek=BgyWEemn2|IXmyV+>-0;RPH|qJbCw9C*(b0O4Rj^ zHvZh|v=rH-3c148sOsi*$y3h3oDZ%Z6D9^L&-6K~;(K;^EY>=Qdry8(alOU~wJGwR zwfA9D-brNa;_<8+hCO>Gc&~ZvBzH#hgtMmpQh92|F8eWWm)+~9_vG`GJs9KAivf!m zTa;nSZPQs3#~wJUDHGmpQ^RB{xT)&efyrzgV53Frs@$mU=$*DPcF7$_+FLihI}aC6 zb_to|gNc(T`Td9e>A=ipJRUaUp%(57!}wyc^aoSzN7E~=c$ zItFdmb(M*Wljt{~f-2awg23wa4G8>Y7Tf>+QB`=+_BIKP?^NLtLDznBw*HTI1n zY$LC+kWk+5iV!d4(&vW}i^uIw0&luQvbpR9S4i9r@vXQ**f`?b!;mwv02dDB-2p;Q z$P5D(qfV}C{SYy0<(hHzL5_KIWf3gb4C|*~&ElMs>yoPzaoyWV#O}oBib$t(LUz~* z3A0rB{OLi&IuTjK`Y>WK^@^t1LjuMfs?I&qg1aK;%NKWCh@ zE7?WA9pXRGOWNIw&q-xikUfy-4wkfzbT5M zD+oXU0uX=z1Rwwb2tWV=5P-nZ6Ts*HNAH**BM3kM0uX=z1Rwwb2tWV=5P-n61#tgA dZBg_G0SG_<0uX=z1Rwwb2tWV=5IA}Q{{n!z)B^wj literal 0 HcmV?d00001 diff --git a/src/uplift/models/gym.py b/src/uplift/models/gym.py new file mode 100644 index 0000000..495ba08 --- /dev/null +++ b/src/uplift/models/gym.py @@ -0,0 +1,49 @@ +import datetime +from database import Base +from sqlalchemy import Column, DateTime, ForeignKey, Integer, Float, String, Boolean, func +from sqlalchemy.orm import backref, relationship +from models.facility import Facility +from models.activity import activities_to_gyms + +class Gym(Base): + __tablename__ = "gym" + + id = Column(Integer, primary_key=True) + name = Column(String(), nullable=False) + description = Column(String(), nullable=False) + activities = relationship( + 'Activity', secondary=activities_to_gyms, back_populates="gyms") + facilities = relationship('Facility', cascade='delete, all') + times = relationship('GymTime', cascade='delete, all') + capacity = relationship('Capacity', cascade='delete, all') + location = Column(String(), nullable=False) + latitude = Column(Integer, nullable=False) + longitude = Column(Float, nullable=False) + image_url = Column(String(), nullable=True) + + def __init__(self, **kwargs): + self.id = kwargs.get("id") + self.name = kwargs.get("name") + self.description = kwargs.get("description") + self.location = kwargs.get("location") + self.latitude = kwargs.get('latitude') + self.longitude = kwargs.get('longitude') + self.image_url = kwargs.get("image_url") + + +class GymTime(Base): + __tablename__ = 'gymtime' + + id = Column(Integer, primary_key=True) + daytime_id = Column(Integer, ForeignKey('daytime.id'), nullable=False) + gym_id = Column(Integer, ForeignKey('gym.id'), nullable=False) + + def __init__(self, **kwargs): + self.daytime_id = kwargs.get("daytime_id") + self.gym_id = kwargs.get("gym_id") + + def serialize(self): + return { + "daytime_id": self.daytime_id, + "gym_id": self.gym_id + } diff --git a/src/uplift/schema.py b/src/uplift/schema.py new file mode 100644 index 0000000..d3b1da8 --- /dev/null +++ b/src/uplift/schema.py @@ -0,0 +1,213 @@ +import datetime as dt +from socketserver import StreamRequestHandler +from xml.sax.handler import property_declaration_handler +from graphene import Field, ObjectType, String, List, Int, Boolean +from graphene.types.datetime import Date, Time +from models.gym import Gym as GymModel, GymTime as GymTimeModel +from models.daytime import DayTime as DayTimeModel +from models.activity import Activity as ActivityModel, ActivityPrice as ActivityPriceModel +from models.capacity import Capacity as CapacityModel +from models.activity import Amenity as AmenityModel +from models.price import Price as PriceModel +from models.facility import Facility as FacilityModel, FacilityPrice as FacilityPriceModel, Equipment as EquipmentModel, FacilityTime as FacilityTimeModel +import graphene +from graphene import relay +from graphene_sqlalchemy import SQLAlchemyConnectionField, SQLAlchemyObjectType +from sqlalchemy import desc + + +class Gym(SQLAlchemyObjectType): + class Meta: + model = GymModel + + times = graphene.List(lambda: DayTime, day=graphene.Int(), start_time=graphene.DateTime( + ), end_time=graphene.DateTime(), restrictions=graphene.String(), special_hours=graphene.Boolean()) + activities = graphene.List(lambda: Activity, name=graphene.String()) + capacities = graphene.List(lambda: Capacity, gym_id=graphene.Int()) + + @staticmethod + def resolve_times(self, info, day=None, start_time=None, end_time=None): + query = GymTime.get_query(info=info) + query = query.filter(GymTimeModel.gym_id == self.id) + query_daytime = DayTime.get_query(info=info) # could be wrong + if day: + query_daytime = query_daytime.filter(DayTimeModel.day == day) + if start_time: + query_daytime = query_daytime.filter(DayTimeModel.start_time == start_time) + if end_time: + query_daytime = query_daytime.filter(DayTimeModel.end_time == end_time) + + daytime_queries = [] + for row in query: + daytime = query_daytime.filter(DayTimeModel.id == row.daytime_id) + if daytime.first(): + daytime_queries.append(daytime[0]) + + return daytime_queries + + def resolve_activities(self, info, name=None): + query = Activity.get_query(info=info) + activity_queries = [] + for act in self.activities: + activity = query.filter(ActivityModel.id == act.id) + if activity.first() and (name == act.name or name == None): + activity_queries.append(activity[0]) + return activity_queries + + @staticmethod + def resolve_capacities(self, info, gym_id=None): + query = Capacity.get_query(info=info) \ + .filter(CapacityModel.gym_id == self.id) \ + .order_by(desc(CapacityModel.updated)) + + return [query.first()] + +class DayTime(SQLAlchemyObjectType): + class Meta: + model = DayTimeModel + +class GymTime(SQLAlchemyObjectType): + class Meta: + model = GymTimeModel + +class Activity(SQLAlchemyObjectType): + class Meta: + model = ActivityModel + + gyms = graphene.List(lambda: Gym, name=graphene.String()) + prices = graphene.List(lambda: Price, cost=graphene.Int(), one_time=graphene.Boolean()) + + def resolve_gyms(self, info, name=None): + query = Gym.get_query(info=info) + gym_queries = [] + for g in self.gyms: + gym = query.filter(GymModel.id == g.id) + if gym.first() and (name == g.name or name == None): + gym_queries.append(gym[0]) + + return gym_queries + + @staticmethod + def resolve_prices(self, info, name=None, cost=None): + query = ActivityPrice.get_query(info=info) + query = query.filter(ActivityPriceModel.activity_id == self.id) + query_price = Price.get_query(info=info) + + if name: + query_price = query_price.filter(PriceModel.name == name) + if cost: + query_price = query_price.filter(PriceModel.cost == cost) + + price_queries = [] + for row in query: + price = query_price.filter(PriceModel.id == row.price_id) + + if price.first(): + price_queries.append(price[0]) + + return price_queries + + +class Capacity(SQLAlchemyObjectType): + class Meta: + model = CapacityModel + + +class Price(SQLAlchemyObjectType): + class Meta: + model = PriceModel + + +class ActivityPrice(SQLAlchemyObjectType): + class Meta: + model = ActivityPriceModel + + +class Facility(SQLAlchemyObjectType): + class Meta: + model = FacilityModel + + @staticmethod + def resolve_times(self, info, day=None, start_time=None, end_time=None): + query = FacilityTime.get_query(info=info) + query = query.filter(FacilityTimeModel.facilty_id == self.id) + query_daytime = DayTime.get_query(info=info) + + if day: + query_datytime = query_daytime.filter(DayTimeModel.day == day) + if start_time: + query_daytime = query_daytime.filter(DayTimeModel.start_time == start_time) + if end_time: + query_daytime = query_daytime.filter(DayTimeModel.end_time == end_time) + + daytime_queries = [] + for row in query: + daytime = query_daytime.filter(DayTimeModel.id == row.daytime_id) + if daytime.first(): + daytime_queries.append(daytime[0]) + + return daytime_queries + + @staticmethod + def resolve_price(self, info, name=None, cost=None): + query = FacilityPrice.get_query(info=info) + query = query.filter(FacilityPriceModel.facility_id == self.id) + query_price = Price.get_query(info=info) + + if name: + query_price = query_price.filter(PriceModel.name == name) + if cost: + query_price = query_price.filter(PriceModel.cost == cost) + + price_queries = [] + for row in query: + price = query_price.filter(PriceModel.id == row.price_id) + + if price.first(): + price_queries.append(price[0]) + + return price_queries + +class FacilityTime(SQLAlchemyObjectType): + class Meta: + model = FacilityTimeModel + +class FacilityPrice(SQLAlchemyObjectType): + class Meta: + model = FacilityPriceModel + +class Equipment(SQLAlchemyObjectType): + class Meta: + model = EquipmentModel + +class Amenity(SQLAlchemyObjectType): + class Meta: + model = AmenityModel + +class Query(graphene.ObjectType): + + gyms = graphene.List(lambda: Gym, + id=graphene.Int(), + name=graphene.String(), + description=graphene.String(), + location=graphene.String(), + latitude=graphene.Float(), + longitude=graphene.Float(), + image_url=graphene.String()) + + def resolve_gyms(self, info, name=None): + query = Gym.get_query(info) + if name: + query = query.filter(GymModel.name == name) + return query.all() + + activities = graphene.List(lambda: Activity, name=graphene.String( + ), details=graphene.String(), image_url=graphene.String()) + + def resolve_activities(self, info, name=None): + query = Activity.get_query(info) + if name: + query = query.filter(ActivityModel.name == name) + return query.all() + +schema = graphene.Schema(query=Query) From b88573aa027987e459a9793d2fdc397c1a733c4c Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Wed, 11 Oct 2023 13:18:54 -0400 Subject: [PATCH 21/39] Activity model and some changes to gym --- manager.py | 4 ++-- src/models/activity.py | 33 +++++++++++++++++++++++++++++++++ src/models/gym.py | 4 ++-- 3 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 src/models/activity.py diff --git a/manager.py b/manager.py index f5815e6..4c58245 100644 --- a/manager.py +++ b/manager.py @@ -1,10 +1,10 @@ import os from flask_script import Manager from flask_migrate import Migrate, MigrateCommand -from app import app, db +from app import app#, db # Build manager -migrate = Migrate(app, db) +#migrate = Migrate(app, db) manager = Manager(app) manager.add_command("db", MigrateCommand) diff --git a/src/models/activity.py b/src/models/activity.py new file mode 100644 index 0000000..468b390 --- /dev/null +++ b/src/models/activity.py @@ -0,0 +1,33 @@ +from sqlalchemy import Column, Float, String, Integer, ForeignKey +from sqlalchemy.orm import relationship +from src.database import Base + +def Activity(Base): + __tablename__ = 'activity' + + id = Column(Integer, primary_key = True) + name = Column(String, nullable=False) + activity_type = Column(Integer, ForeignKey('activitytype.id'), nullable=False) + facility_id = Column(Integer, ForeignKey('facility.id'), nullable=False) + prices = relationship('Price') + image_url = Column(String(), nullable=False) + + def __init__(self, **kwargs): + self.id = kwargs.get('id') + self.name = kwargs.get('name') + self.activity_type = kwargs.get('activity_type') + self.facility_id = kwargs.get('facility_id') + self.image_url = kwargs.get('image_url') + + +def ActivityType(Base): + __tablename__ = 'activitytype' + + id = Column(Integer, primary_key=True) + name = Column(String, nullable=False) + + def __init__(self, **kwargs): + self.id = kwargs.get('id') + self.name = kwargs.get('name') + + diff --git a/src/models/gym.py b/src/models/gym.py index 39c8b6d..7db9483 100644 --- a/src/models/gym.py +++ b/src/models/gym.py @@ -10,8 +10,8 @@ class Gym(Base): description = Column(String(1000), nullable=False) facilities = relationship("Facility") - # TODO: - Complete capacity table - # capacity = relationship('Capacity', cascade='delete, all') + + # TODO: - complete amenities table and scraper location=Column(String(1000), nullable=False) latitude=Column(Float, nullable=False) From 1650a554ee6dc034d73332b768fedbf54a65ec03 Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Tue, 17 Oct 2023 00:02:14 -0400 Subject: [PATCH 22/39] Created some of gym scraper --- src/app2/models/gym.py => T | 0 src/app2/database.py | 90 ------------- src/app2/database.py.orig | 91 ------------- src/app2/database.sqlite3 | Bin 36864 -> 0 bytes src/app2/models/activity.py | 62 --------- src/database.py | 1 - src/models/capacity.py | 3 +- src/models/facility.py | 129 +++---------------- src/models/gym.py | 4 +- src/models/openhours.py | 6 +- src/{app2/schema.py => scrapers/__init__.py} | 0 src/scrapers/gym_scraper.py | 103 +++++++++++++++ src/test.py | 7 - 13 files changed, 127 insertions(+), 369 deletions(-) rename src/app2/models/gym.py => T (100%) delete mode 100644 src/app2/database.py delete mode 100644 src/app2/database.py.orig delete mode 100644 src/app2/database.sqlite3 delete mode 100644 src/app2/models/activity.py rename src/{app2/schema.py => scrapers/__init__.py} (100%) create mode 100644 src/scrapers/gym_scraper.py delete mode 100644 src/test.py diff --git a/src/app2/models/gym.py b/T similarity index 100% rename from src/app2/models/gym.py rename to T diff --git a/src/app2/database.py b/src/app2/database.py deleted file mode 100644 index a676da0..0000000 --- a/src/app2/database.py +++ /dev/null @@ -1,90 +0,0 @@ -from sqlalchemy import create_engine -from sqlalchemy.ext.declarative import declarative_base -from sqlalchemy.orm import scoped_session, sessionmaker -import datetime - -engine = create_engine("sqlite:///database.sqlite3") -db_session = scoped_session( - sessionmaker(autocommit=False, autoflush=False, bind=engine) -) -Base = declarative_base() -Base.query = db_session.query_property() - -def init_db(): - # import all modules that might define models so they will be registered properly - # on metadata - otherwise import them first before calling init_db() - from models.gym import Gym, GymTime - from models.daytime import DayTime - from models.activity import Activity, Price, Amenity - - Base.metadata.drop_all(bind=engine) - Base.metadata.create_all(bind=engine) - - gym_1 = Gym(name='Helen Newman', description='Something', - location='North', image_url='something') - db_session.add(gym_1) - daytime_1 = DayTime(day=1, start_time=datetime.datetime.utcnow( - ), end_time=datetime.datetime.utcnow(), restrictions='None', special_hours=True) - db_session.add(daytime_1) - db_session.commit() - - gymtime_1 = GymTime(daytime_id=daytime_1.id, gym_id=gym_1.id) - db_session.add(gymtime_1) - db_session.commit() - - activity_1 = Activity( - name='Volleyball', details='It fun', image_url='None') - db_session.add(activity_1) - db_session.commit() - - # adding the gym Helen Newman to the activity Volleyball - activity_1.gyms.append(gym_1) - db_session.add(activity_1) - db_session.commit() - - price_1 = Price(name="price1", cost=20, one_time=False, image_url="none", activity_id=activity_1.id) - db_session.add(price_1) - db_session.commit() - activity_1.prices.append(price_1) - db_session.add(activity_1) - db_session.commit() - - price_2 = Price(name="price2", cost=40, one_time=True, image_url="n/a", activity_id = activity_1.id) - db_session.add(price_2) - db_session.commit() - activity_1.prices.append(price_2) - db_session.add(activity_1) - db_session.commit() - - amenity_1 = Amenity(name="locker", image_url="none", activity_id=activity_1.id) - db_session.add(amenity_1) - db_session.commit() - activity_1.amenities.append(amenity_1) - db_session.add(activity_1) - db_session.commit() - - gym_2 = Gym(name="Morrison", description="Nicer", - location="North", image_url="N/A") - db_session.add(gym_2) - daytime_2 = DayTime(day=2, start_time=datetime.datetime.utcnow( - ), end_time=datetime.datetime.utcnow(), restrictions="A few", special_hours=False) - db_session.add(daytime_2) - db_session.commit() - - gymtime_2 = GymTime(daytime_id=daytime_2.id, gym_id=gym_2.id) - db_session.add(gymtime_2) - db_session.commit() - - activity_2 = Activity(name="Dancing", details="more fun", image_url="No") - db_session.add(activity_2) - db_session.commit() - - activity_2.gyms.append(gym_1) - activity_2.gyms.append(gym_2) - db_session.add(activity_2) - db_session.commit() - - - - - diff --git a/src/app2/database.py.orig b/src/app2/database.py.orig deleted file mode 100644 index a5831ee..0000000 --- a/src/app2/database.py.orig +++ /dev/null @@ -1,91 +0,0 @@ -from sqlalchemy import create_engine -from sqlalchemy.ext.declarative import declarative_base -from sqlalchemy.orm import scoped_session, sessionmaker -import datetime - -engine = create_engine("sqlite:///database.sqlite3") -db_session = scoped_session( - sessionmaker(autocommit=False, autoflush=False, bind=engine) -) -Base = declarative_base() -Base.query = db_session.query_property() - -def init_db(): - # import all modules that might define models so they will be registered properly - # on metadata - otherwise import them first before calling init_db() - from models.gym import Gym, GymTime - from models.daytime import DayTime - from models.activity import Activity, Price, Amenity - - Base.metadata.drop_all(bind=engine) - Base.metadata.create_all(bind=engine) - - gym_1 = Gym(name='Helen Newman', description='Something', - location='North', image_url='something') - db_session.add(gym_1) - daytime_1 = DayTime(day=1, start_time=datetime.datetime.utcnow( - ), end_time=datetime.datetime.utcnow(), restrictions='None', special_hours=True) - db_session.add(daytime_1) - db_session.commit() - - gymtime_1 = GymTime(daytime_id=daytime_1.id, gym_id=gym_1.id) - db_session.add(gymtime_1) - db_session.commit() - - activity_1 = Activity( - name='Volleyball', details='It fun', image_url='None') - db_session.add(activity_1) - db_session.commit() - - # adding the gym Helen Newman to the activity Volleyball - activity_1.gyms.append(gym_1) - db_session.add(activity_1) - db_session.commit() - - price_1 = Price(name="price1", cost=20, one_time=False, image_url="none", activity_id=activity_1.id) - db_session.add(price_1) - db_session.commit() - activity_1.prices.append(price_1) - db_session.add(activity_1) - db_session.commit() - - price_2 = Price(name="price2", cost=40, one_time=True, image_url="n/a", activity_id = activity_1.id) - db_session.add(price_2) - db_session.commit() - activity_1.prices.append(price_2) - db_session.add(activity_1) - db_session.commit() - - amenity_1 = Amenity(name="locker", image_url="none", activity_id=activity_1.id) - db_session.add(amenity_1) - db_session.commit() - activity_1.amenities.append(amenity_1) - db_session.add(activity_1) - db_session.commit() - - gym_2 = Gym(name="Morrison", description="Nicer", - location="North", image_url="N/A") - db_session.add(gym_2) - daytime_2 = DayTime(day=2, start_time=datetime.datetime.utcnow( - ), end_time=datetime.datetime.utcnow(), restrictions="A few", special_hours=False) - db_session.add(daytime_2) - db_session.commit() - - gymtime_2 = GymTime(daytime_id=daytime_2.id, gym_id=gym_2.id) - db_session.add(gymtime_2) - db_session.commit() - - activity_2 = Activity(name="Dancing", details="more fun", image_url="No") - db_session.add(activity_2) - db_session.commit() - - activity_2.gyms.append(gym_1) - activity_2.gyms.append(gym_2) - db_session.add(activity_2) - db_session.commit() - -def merge(): - pass - - - diff --git a/src/app2/database.sqlite3 b/src/app2/database.sqlite3 deleted file mode 100644 index 515f80ebcd7abd62e216633e0a5994606f941598..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36864 zcmeI*?QhdY90%|_Cr#p_;6ayJRaJ3&F)0xR@<3TZnwSZOMzjt~J0`Rjkx5Kz&9OV% z9jnwgwER)L+WvyQ+zX_=JoGTs?M^=-pD?c~#hTw(_`}kHRj6Ve13K zHvPSLRY-*$S567r=3Ur5rPEwh(jMkO-!i(pu9dU~Vd*{J{D!~Tzoi)3J{4S2A4hnw zlFQ4oOrNyF2zOkwXM~GhDWrYB{sCtNTgApRFJ%C>^K?T&G6Vt>f?NB&gA4TYLu9E z-}u)1+Txc+U47Sg!q?rn^N>-uHd>eCvsfXR$qq`HaQHo;VRFX9I9_E_mM@3+v{`2? zn&<1TA7$Z9K8tO(*40!R8g_q5t7~{ZA2Yt`*j_SxkMh*pF?yzMb+?^e*BhJUsZ$ou zXmO^dH$F;NJ}q^GygWBY4^JhtF+XdWlt*|PCt3_oMWe&DZ+Jb|+zDbzhm>-$oSyy< zU8aoSSL5bEEz`WbxJVB^iRRjP{!8*pNQIZwzUGvaI`F>X>!$U}*-G_zqvI~}L=~hT zi1eH4uD5N622;+dPe-81d2f#dRj?C;u|Gf!v8 zhx4U-j%68p4|L0F`B8&yMA!dMiS(oN^z9E2M+gB3KmY;|fB*y_009U<00Iy=Spo|} zjx5UZ+`8ksrsvoizw^n}9M|90E-4k7BOjfU&#fAkVKdEmG|=r0XJGi-{9}Qzlb5`T zuK)Lm^u4ryvIG$=1Rwwb2tWV=5P$##AOHafK;ZuoP=q|8iXs<;dbQrTP`!MieudTR z*BV!^RWDz>^6_%Lwlb-u-cZ;>DLo=c{%VWw&FM{j;-}njz z0uX=z1Rwwb2tWV=5P$##AOL}5E|AaC;Oak<%ZlNr09jEKqx=7#5$T2W?3jm#!-oI_ zAOHafKmY;|fB*y_009V`Jb^R(%LVgPoD;(zKdG1POZr*oh(J!rlJNF_nkAz6H{@J=*8l(j diff --git a/src/app2/models/activity.py b/src/app2/models/activity.py deleted file mode 100644 index 470535f..0000000 --- a/src/app2/models/activity.py +++ /dev/null @@ -1,62 +0,0 @@ -import datetime -from typing import Counter -from database import Base -from sqlalchemy import Table, Column, Integer, DateTime, ForeignKey, String, Boolean, null -from sqlalchemy.orm import relationship - -activities_to_gyms = Table( - "activities_to_gyms", - Base.metadata, - Column("gym_id", ForeignKey("gym.id"), primary_key=True), - Column("activity_id", ForeignKey("activity.id"), primary_key=True), -) - - -class Activity(Base): - __tablename__ = "activity" - - id = Column(Integer, primary_key=True) - name = Column(String(), nullable=False) - details = Column(String(1000), nullable=False) - gyms = relationship('Gym', secondary=activities_to_gyms, - back_populates="activities") - prices = relationship('Price', cascade='delete, all') - amenities = relationship('Amenity', cascade='delete, all') - image_url = Column(String(1000), nullable=True) - - def __init__(self, **kwargs): - self.name = kwargs.get("name") - self.details = kwargs.get("details") - self.image_url = kwargs.get("image_url") - - -class Price(Base): - __tablename__ = "price" - - id = Column(Integer, primary_key=True) - name = Column(String(100), nullable=False) - cost = Column(Integer, nullable=False) - one_time = Column(Boolean, nullable=False) - image_url = Column(String(1000), nullable=True) - activity_id = Column(Integer, ForeignKey('activity.id'), nullable=False) - - def __init__(self, **kwargs): - self.name = kwargs.get("name") - self.cost = kwargs.get("cost") - self.one_time = kwargs.get("one_time") - self.image_url = kwargs.get("image_url") - self.activity_id = kwargs.get("activity_id") - - -class Amenity(Base): - __tablename__ = 'amenity' - - id = Column(Integer, primary_key=True) - name = Column(String(), nullable=False) - image_url = Column(String(), nullable=True) - activity_id = Column(Integer, ForeignKey('activity.id'), nullable=False) - - def __init__(self, **kwargs): - self.name = kwargs.get("name") - self.image_url = kwargs.get("image_url") - self.activity_id = kwargs.get("activity_id") diff --git a/src/database.py b/src/database.py index 4eb9e96..3bd6b09 100644 --- a/src/database.py +++ b/src/database.py @@ -4,7 +4,6 @@ from sqlalchemy.orm import scoped_session, sessionmaker -# engine = create_engine("sqlite:///database.sqlite3") db_user = os.environ.get("DB_USERNAME") db_password = os.environ.get("DB_PASSWORD") db_name = os.environ.get("DB_NAME") diff --git a/src/models/capacity.py b/src/models/capacity.py index 7810800..40ffbf4 100644 --- a/src/models/capacity.py +++ b/src/models/capacity.py @@ -1,6 +1,7 @@ + from sqlalchemy import Column, ForeignKey, Integer, DateTime, Float from sqlalchemy.orm import backref, relationship -from src.database import Base +from ..database import Base """ Store counts for each Gym """ diff --git a/src/models/facility.py b/src/models/facility.py index 96599b0..72b10a9 100644 --- a/src/models/facility.py +++ b/src/models/facility.py @@ -1,20 +1,13 @@ -<<<<<<< HEAD:src/models/facility.py -<<<<<<<< HEAD:src/models/facility.py +import sys +sys.path.append('..') import enum from sqlalchemy import Column, ForeignKey, String, Enum, Integer -======== -import datetime -from importlib.machinery import FrozenImporter -from typing import Counter -from database import Base -from sqlalchemy import Table, Column, Integer, DateTime, ForeignKey, String, Boolean, null ->>>>>>>> 2eebca9 (almost implementing Facilities):src/uplift/models/activity.py from sqlalchemy.orm import relationship from src.database import Base -from src.models.openhours import OpenHours from src.models.capacity import Capacity + class FacilityType(enum.Enum): fitness = 0 @@ -25,23 +18,12 @@ class Facility(Base): id = Column(Integer, primary_key=True) gym_id = Column(Integer, ForeignKey("gym.id"), nullable=False) name = Column(String(), nullable=False) -<<<<<<<< HEAD:src/models/facility.py facility_type = Column(Enum(FacilityType), nullable=False) open_hours = relationship("OpenHours") capacities = relationship("Capacity") # TODO: - Implement the following - # prices = relationship('Price', cascade='delete, all') - # amenities = relationship('Amenity', cascade='delete, all') # image_url = Column(String(1000), nullable=True) -======== - details = Column(String(), nullable=False) - gyms = relationship('Gym', secondary=activities_to_gyms, - back_populates="activities") - prices = relationship('ActivityPrice', cascade='delete, all') - amenities = relationship('Amenity', cascade='delete, all') - image_url = Column(String(), nullable=True) ->>>>>>>> 2eebca9 (almost implementing Facilities):src/uplift/models/activity.py def __init__(self, **kwargs): self.id = kwargs.get("id") @@ -52,35 +34,20 @@ def __init__(self, **kwargs): # TODO: - Implement the following # self.image_url = kwargs.get("image_url") - def serialize(self): - return { - "id": self.id, - "name": self.name, - "gym_id": self.gym_id, - "facility_type": self.facility_type, - "capacities": self.capacities, - } + # def serialize(self): + # return { + # "id": self.id, + # "name": self.name, + # "gym_id": self.gym_id, + # "facility_type": self.facility_type, + # "capacities": self.capacities, + # } -<<<<<<<< HEAD:src/models/facility.py # Left here as a reference for the above TODOs -""" -class Price(Base): - __tablename__ = "price" -======== -class ActivityPrice(Base): - __tablename__ = "activityprice" ->>>>>>>> 2eebca9 (almost implementing Facilities):src/uplift/models/activity.py - - id = Column(Integer, primary_key=True) - activity_id = Column(Integer, ForeignKey('activity.id'), nullable=False) - price_id = Column(Integer, ForeignKey('price.id'), nullable=False) - - def __init__(self, **kwargs): - self.activity_id = kwargs.get("activity_id") - self.price = kwargs.get("price_id") +""" class Amenity(Base): __tablename__ = 'amenity' @@ -93,72 +60,10 @@ def __init__(self, **kwargs): self.name = kwargs.get("name") self.image_url = kwargs.get("image_url") self.activity_id = kwargs.get("activity_id") -""" -======= -from ast import For -from database import Base -from sqlalchemy import Column, DateTime, ForeignKey, Integer, Float, String, func -from sqlalchemy.orm import backref, relationship -from models.price import Price - - -class Facility(Base): - __tablename__ = "facility" - - id = Column(Integer, primary_key=True) - name = Column(String(), nullable=False) - times = relationship('FacilityTime', cascade='delete, all') - price = relationship('Price', cascade='delete, all') - equipment = relationship('Equipment', cascade='delete, all') - image_url = Column(String(), nullable=True) - - def __init__(self, **kwargs): - self.name = kwargs.get("name") - self.image_url = kwargs.get("image") - - -class FacilityTime(Base): - __tablename__ = "facilitytime" - id = Column(Integer, primary_key=True) - facilty_id = Column(Integer, ForeignKey('facility.id'), nullable=False) - daytime_id = Column(Integer, ForeignKey('daytime.id'), nullable=False) - def __init__(self, **kwargs): - self.facility_id = kwargs.get("facility_id") - self.daytime_id = kwargs.get("daytime_id") - -class FacilityPrice(Base): - __tablename__ = "facilityprice" - - id = Column(Integer, primary_key=True) - facility_id = Column(Integer, ForeignKey('facility.id'), nullable=False) - price_id = Column(Integer, ForeignKey('price.id'), nullable=False) - - def __init__(self, **kwargs): - self.facility_id=kwargs.get("facility_id") - self.price_id=kwargs.get("price_id") - - -class Equipment(Base): - __tablename__ = "equipment" - - id = Column(Integer, primary_key=True) - equipment_type = Column(String(), nullable=False) - name = Column(String(), nullable=False) - quantity = Column(Integer, nullable=False) - facility_id = Column(Integer, ForeignKey('facility.id'), nullable=False) - - def __init__(self, **kwargs): - self.equipment_type = kwargs.get("equipment_type") - self.name = kwargs.get("name") - self.quantity = kwargs.get("quantity") - self.facility_id=kwargs.get("facility_id") - - - - - - - ->>>>>>> 2eebca9 (almost implementing Facilities):src/uplift/models/facility.py + def __init__(self, **kwargs): + self.name = kwargs.get("name") + self.image_url = kwargs.get("image_url") + self.activity_id = kwargs.get("activity_id") +""" \ No newline at end of file diff --git a/src/models/gym.py b/src/models/gym.py index 7db9483..e335aed 100644 --- a/src/models/gym.py +++ b/src/models/gym.py @@ -3,15 +3,15 @@ from src.database import Base class Gym(Base): - __tablename__ = "gym" + __tablename__ = 'gym' id = Column(Integer, primary_key=True) name = Column(String(100), nullable=False) description = Column(String(1000), nullable=False) facilities = relationship("Facility") - # TODO: - complete amenities table and scraper + # # amenities = relationship('Amenity', cascade='delete, all') location=Column(String(1000), nullable=False) latitude=Column(Float, nullable=False) diff --git a/src/models/openhours.py b/src/models/openhours.py index b9809b4..e435341 100644 --- a/src/models/openhours.py +++ b/src/models/openhours.py @@ -1,4 +1,4 @@ -from sqlalchemy import Column, ForeignKey, Integer, Float +from sqlalchemy import Column, ForeignKey, Integer, Float, String from src.database import Base class OpenHours(Base): @@ -7,8 +7,8 @@ class OpenHours(Base): id = Column(Integer, primary_key=True) facility_id = Column(Integer, ForeignKey("facility.id"), nullable=False) day = Column(Integer, nullable=False) - start_time = Column(Float, nullable=False) # TODO: - Convert to DateTime - end_time = Column(Float, nullable=False) + start_time = Column(String(), nullable=False) # TODO: - Convert to DateTime + end_time = Column(String(), nullable=False) # TODO: - Handle restrictions and special hours # restrictions = Column(String(1000)) # special_hours = Column(Boolean, nullable=False) diff --git a/src/app2/schema.py b/src/scrapers/__init__.py similarity index 100% rename from src/app2/schema.py rename to src/scrapers/__init__.py diff --git a/src/scrapers/gym_scraper.py b/src/scrapers/gym_scraper.py new file mode 100644 index 0000000..21fa07d --- /dev/null +++ b/src/scrapers/gym_scraper.py @@ -0,0 +1,103 @@ +import sys +sys.path.append('..') +from database import db_session +from bs4 import BeautifulSoup +import requests +from models.facility import Facility, FacilityType +from models.openhours import OpenHours +from models.gym import Gym + +# BASE_URL = 'https://scl.cornell.edu/recreation' +BASE_URL_CENTERS = 'https://scl.cornell.edu/recreation/cornell-fitness-centers' +NEWMAN = 'https://scl.cornell.edu/recreation/facility/helen-newman-fitness-center' +result = requests.get(BASE_URL_CENTERS).text + +type = FacilityType(name='Fitness Center') + +def create_fitcenter_object(h_ref): + page = requests.get(NEWMAN).text + soup = BeautifulSoup(page, 'lxml') + + box = soup.find('article', id='main-article', class_='primary') + facility_name = box.find('h1').get_text() + + facility = Facility(name=facility_name, facility_type=type.id) + + db_session.add(facility) + db_session.commit() + print(facility_name) + return facility + +def scrape_fitcenters(): + centers = {} + page = requests.get(BASE_URL_CENTERS).text + soup = BeautifulSoup(page, 'lxml') + table = soup.find('table', class_='colored striped') + data = table.find_all('tr')[1:] + for row in data: + row_eles = row.find_all('td') + + week_times = row_eles[1].text.strip() + week_times = week_times.split('/') + + for time in week_times: + time = time.strip() + time = time.split('-') + time = [t.strip() for t in time] + + + + + wkend_time = row_eles[2].text + + +page = requests.get(BASE_URL_CENTERS).text +soup = BeautifulSoup(page, 'lxml') +table = soup.find('table', class_='colored striped') +data = table.find_all('tr')[1:] +time = [] +for row in data: + row_eles = row.find_all('td') + name = row_eles[0].text.strip() + print(row_eles[1].text) + print(row_eles[2].text) + + #standard week times + week_times = row_eles[1].text.strip() + week_times = week_times.split('/') + + for time in week_times: + time = time.strip() + time = time.split('-') + time = [t.strip() for t in time] + + # case when don't have start and end time + if len(time) != 2: + continue + + am = time[0].find('am') != -1 + stime_loc = time[0].lower().find('am') if am else time[0].lower().find('pm') + etime_loc = time[1].lower().find('am') if am else time[1].lower().find('pm') + + start = time[0][:stime_loc].strip() + start = start + 'am' if am else start + 'pm' + end = time[1][:etime_loc].strip() + end = end + 'am' if am else end + 'pm' + + #get facility id for specific fitness center + gym = db_session.query(Gym).filter(Gym.name == name).first() + # facilities = db_session.query(Facility).filter(Facility.gym_id == gym.id) + #get facility id and check if + for i in range(1, 6): + hour = OpenHours(day=i, start_time=start, end_time=end) + # db_session.add(hour) + # db_session.commit() + + + + + + + + + diff --git a/src/test.py b/src/test.py deleted file mode 100644 index 9e53272..0000000 --- a/src/test.py +++ /dev/null @@ -1,7 +0,0 @@ -from models.activity import Activity, ActivityType -from database import db_session, Base - -def testGym(): - -def testActivity(): - \ No newline at end of file From 6319953d8e803da7a3eedf648ccf3149fe69c3f6 Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Tue, 17 Oct 2023 00:10:22 -0400 Subject: [PATCH 23/39] fixed facility.py --- src/models/facility.py | 92 +++--------------------------------------- 1 file changed, 6 insertions(+), 86 deletions(-) diff --git a/src/models/facility.py b/src/models/facility.py index 96599b0..fd0af5a 100644 --- a/src/models/facility.py +++ b/src/models/facility.py @@ -1,14 +1,6 @@ -<<<<<<< HEAD:src/models/facility.py -<<<<<<<< HEAD:src/models/facility.py + import enum from sqlalchemy import Column, ForeignKey, String, Enum, Integer -======== -import datetime -from importlib.machinery import FrozenImporter -from typing import Counter -from database import Base -from sqlalchemy import Table, Column, Integer, DateTime, ForeignKey, String, Boolean, null ->>>>>>>> 2eebca9 (almost implementing Facilities):src/uplift/models/activity.py from sqlalchemy.orm import relationship from src.database import Base from src.models.openhours import OpenHours @@ -25,7 +17,7 @@ class Facility(Base): id = Column(Integer, primary_key=True) gym_id = Column(Integer, ForeignKey("gym.id"), nullable=False) name = Column(String(), nullable=False) -<<<<<<<< HEAD:src/models/facility.py + facility_type = Column(Enum(FacilityType), nullable=False) open_hours = relationship("OpenHours") capacities = relationship("Capacity") @@ -34,14 +26,9 @@ class Facility(Base): # prices = relationship('Price', cascade='delete, all') # amenities = relationship('Amenity', cascade='delete, all') # image_url = Column(String(1000), nullable=True) -======== - details = Column(String(), nullable=False) - gyms = relationship('Gym', secondary=activities_to_gyms, - back_populates="activities") - prices = relationship('ActivityPrice', cascade='delete, all') - amenities = relationship('Amenity', cascade='delete, all') - image_url = Column(String(), nullable=True) ->>>>>>>> 2eebca9 (almost implementing Facilities):src/uplift/models/activity.py + + + def __init__(self, **kwargs): self.id = kwargs.get("id") @@ -61,7 +48,7 @@ def serialize(self): "capacities": self.capacities, } -<<<<<<<< HEAD:src/models/facility.py + # Left here as a reference for the above TODOs @@ -94,71 +81,4 @@ def __init__(self, **kwargs): self.image_url = kwargs.get("image_url") self.activity_id = kwargs.get("activity_id") """ -======= -from ast import For -from database import Base -from sqlalchemy import Column, DateTime, ForeignKey, Integer, Float, String, func -from sqlalchemy.orm import backref, relationship -from models.price import Price - - -class Facility(Base): - __tablename__ = "facility" - - id = Column(Integer, primary_key=True) - name = Column(String(), nullable=False) - times = relationship('FacilityTime', cascade='delete, all') - price = relationship('Price', cascade='delete, all') - equipment = relationship('Equipment', cascade='delete, all') - image_url = Column(String(), nullable=True) - - def __init__(self, **kwargs): - self.name = kwargs.get("name") - self.image_url = kwargs.get("image") - - -class FacilityTime(Base): - __tablename__ = "facilitytime" - - id = Column(Integer, primary_key=True) - facilty_id = Column(Integer, ForeignKey('facility.id'), nullable=False) - daytime_id = Column(Integer, ForeignKey('daytime.id'), nullable=False) - - def __init__(self, **kwargs): - self.facility_id = kwargs.get("facility_id") - self.daytime_id = kwargs.get("daytime_id") - -class FacilityPrice(Base): - __tablename__ = "facilityprice" - - id = Column(Integer, primary_key=True) - facility_id = Column(Integer, ForeignKey('facility.id'), nullable=False) - price_id = Column(Integer, ForeignKey('price.id'), nullable=False) - - def __init__(self, **kwargs): - self.facility_id=kwargs.get("facility_id") - self.price_id=kwargs.get("price_id") - - -class Equipment(Base): - __tablename__ = "equipment" - - id = Column(Integer, primary_key=True) - equipment_type = Column(String(), nullable=False) - name = Column(String(), nullable=False) - quantity = Column(Integer, nullable=False) - facility_id = Column(Integer, ForeignKey('facility.id'), nullable=False) - - def __init__(self, **kwargs): - self.equipment_type = kwargs.get("equipment_type") - self.name = kwargs.get("name") - self.quantity = kwargs.get("quantity") - self.facility_id=kwargs.get("facility_id") - - - - - - ->>>>>>> 2eebca9 (almost implementing Facilities):src/uplift/models/facility.py From 5396f9b5590efe31f82430f5bd8bce8858f6f7a9 Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Thu, 19 Oct 2023 21:05:14 -0400 Subject: [PATCH 24/39] wrote some of gym hour scraper --- Dockerfile | 3 + schema.graphql | 4 +- src/models/capacity.py | 2 +- src/models/facility.py | 4 +- src/models/gym.py | 2 +- src/models/openhours.py | 2 +- src/scrapers/gym_scraper.py | 106 ++++++++++++++++++++++++------------ 7 files changed, 81 insertions(+), 42 deletions(-) diff --git a/Dockerfile b/Dockerfile index 72b28c8..33217ac 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,6 +5,9 @@ WORKDIR /usr/src/app COPY . . +ENV MAX_CONCURRENT_PIP=4 + +RUN pip install --upgrade pip RUN pip install -r requirements.txt RUN python c2c_scraper.py diff --git a/schema.graphql b/schema.graphql index abc99d3..ebbff35 100644 --- a/schema.graphql +++ b/schema.graphql @@ -41,8 +41,8 @@ type OpenHours { id: ID! facilityId: Int! day: Int! - startTime: Float! - endTime: Float! + startTime: String! + endTime: String! } type Query { diff --git a/src/models/capacity.py b/src/models/capacity.py index 40ffbf4..6331eb6 100644 --- a/src/models/capacity.py +++ b/src/models/capacity.py @@ -1,7 +1,7 @@ from sqlalchemy import Column, ForeignKey, Integer, DateTime, Float from sqlalchemy.orm import backref, relationship -from ..database import Base +from database import Base """ Store counts for each Gym """ diff --git a/src/models/facility.py b/src/models/facility.py index 72b10a9..e848c5a 100644 --- a/src/models/facility.py +++ b/src/models/facility.py @@ -3,8 +3,8 @@ import enum from sqlalchemy import Column, ForeignKey, String, Enum, Integer from sqlalchemy.orm import relationship -from src.database import Base -from src.models.capacity import Capacity +from database import Base +from models.capacity import Capacity diff --git a/src/models/gym.py b/src/models/gym.py index e335aed..2b9e8d4 100644 --- a/src/models/gym.py +++ b/src/models/gym.py @@ -1,6 +1,6 @@ from sqlalchemy import Column, Float, String, Integer from sqlalchemy.orm import relationship -from src.database import Base +from database import Base class Gym(Base): __tablename__ = 'gym' diff --git a/src/models/openhours.py b/src/models/openhours.py index e435341..a20f199 100644 --- a/src/models/openhours.py +++ b/src/models/openhours.py @@ -1,5 +1,5 @@ from sqlalchemy import Column, ForeignKey, Integer, Float, String -from src.database import Base +from database import Base class OpenHours(Base): __tablename__ = "openhours" diff --git a/src/scrapers/gym_scraper.py b/src/scrapers/gym_scraper.py index 21fa07d..415b1e0 100644 --- a/src/scrapers/gym_scraper.py +++ b/src/scrapers/gym_scraper.py @@ -12,8 +12,6 @@ NEWMAN = 'https://scl.cornell.edu/recreation/facility/helen-newman-fitness-center' result = requests.get(BASE_URL_CENTERS).text -type = FacilityType(name='Fitness Center') - def create_fitcenter_object(h_ref): page = requests.get(NEWMAN).text soup = BeautifulSoup(page, 'lxml') @@ -48,50 +46,88 @@ def scrape_fitcenters(): - wkend_time = row_eles[2].text - - -page = requests.get(BASE_URL_CENTERS).text -soup = BeautifulSoup(page, 'lxml') -table = soup.find('table', class_='colored striped') -data = table.find_all('tr')[1:] -time = [] -for row in data: - row_eles = row.find_all('td') - name = row_eles[0].text.strip() - print(row_eles[1].text) - print(row_eles[2].text) - - #standard week times - week_times = row_eles[1].text.strip() - week_times = week_times.split('/') - - for time in week_times: - time = time.strip() - time = time.split('-') - time = [t.strip() for t in time] +def create_openhours(times_set, name, days): + for time in times_set: + times = time.strip().split('-') + times = [t.strip() for t in times] # case when don't have start and end time - if len(time) != 2: + if len(times) != 2: continue - am = time[0].find('am') != -1 - stime_loc = time[0].lower().find('am') if am else time[0].lower().find('pm') - etime_loc = time[1].lower().find('am') if am else time[1].lower().find('pm') + am = times[0].lower().find('am') != -1 + stime_loc = times[0].lower().find('am') if am else times[0].lower().find('pm') + etime_loc = times[1].lower().find('am') if am else times[1].lower().find('pm') - start = time[0][:stime_loc].strip() + start = times[0][:stime_loc].strip() start = start + 'am' if am else start + 'pm' - end = time[1][:etime_loc].strip() + end = times[1][:etime_loc].strip() end = end + 'am' if am else end + 'pm' #get facility id for specific fitness center gym = db_session.query(Gym).filter(Gym.name == name).first() - # facilities = db_session.query(Facility).filter(Facility.gym_id == gym.id) - #get facility id and check if + facility = db_session.query(Facility).filter(Facility.gym_id == gym.id).first() + + + #put an open hour for each day: 1 = Monday, 2 = Tuesday, etc. for i in range(1, 6): - hour = OpenHours(day=i, start_time=start, end_time=end) - # db_session.add(hour) - # db_session.commit() + try: + hour = db_session.query(OpenHours).filter(OpenHours.facility_id==facility.id, OpenHours.day == i, OpenHours.start_time == start, OpenHours.end_time == end).first() + assert hour is not None + except AssertionError: + hour = OpenHours(facility_id=facility.id, day=i, start_time=start, end_time=end) + db_session.add(hour) + db_session.commit() + +days_to_nums = { + 'monday': 1, + 'tuesday': 2, + 'wednesday': 3, + 'thursday': 4, + 'friday': 5, + 'saturday': 6, + 'sunday': 7, +} + +page = requests.get(BASE_URL_CENTERS).text +soup = BeautifulSoup(page, 'lxml') +table = soup.find('table', class_='colored striped') +data = table.find_all('tr') + +#finding the days - (for break hours this is necessary) +day_set = data[0].find_all('th')[1:] +day_set = [days.text.strip().split('-') for days in day_set] + +for i, days in enumerate(day_set): + if days[0].lower() == 'weekdays': + day_set[i] = [1, 6] + elif days[0].lower() == 'weekend': + day_set[i] = [6, 8] + else: + converted = [] + for day in days: + converted.append(days_to_nums[day.strip().lower()]) + if len(converted == 1): + converted.append(converted[0]+1) + day_set[i] = converted + +for days in day_set: + print(str(days)) + + + +# for row in data[1:]: +# row_eles = row.find_all('td') +# name = row_eles[0].text.strip() +# print(row_eles[1].text) +# print(row_eles[2].text) + +# for i in range(1, len(days)+1): +# times = row_eles[i].text.strip().split('/') + +# create_openhours(times, name, ) + + From 228a2618474f7f40b9ea8c36277b569cd02612ca Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Wed, 1 Nov 2023 16:16:53 -0400 Subject: [PATCH 25/39] Implement scraper for fitness center hours --- app.py | 2 + src/constants.json | 76 ++-------------- src/constants.py | 5 - src/models/capacity.py | 2 +- src/models/classes.py | 2 +- src/models/facility.py | 4 +- src/models/openhours.py | 2 +- src/scrapers/gym_scraper.py | 176 ++++++++++++++++-------------------- 8 files changed, 93 insertions(+), 176 deletions(-) diff --git a/app.py b/app.py index 1baf7b4..f1b45c7 100644 --- a/app.py +++ b/app.py @@ -6,6 +6,7 @@ from src.schema import Query from src.constants import create_gym_table from src.scrapers.scraper import scrape_classes +from src.scrapers.gym_scraper import scrape_times app = Flask(__name__) @@ -31,6 +32,7 @@ def shutdown_session(exception=None): init_db() create_gym_table() scrape_classes(1) +scrape_times() # Create schema.graphql with open("schema.graphql", "w+") as schema_file: diff --git a/src/constants.json b/src/constants.json index 08e51ac..8f662b6 100644 --- a/src/constants.json +++ b/src/constants.json @@ -12,18 +12,7 @@ { "name": "Helen Newman", "type": "fitness", - "hours": [ - { - "start": 6, - "end": 21, - "weekday": true - }, - { - "start": 10, - "end": 20, - "weekday": false - } - ] + "hours": [] } ] }, @@ -39,18 +28,7 @@ { "name": "Toni Morrison", "type": "fitness", - "hours": [ - { - "start": 14, - "end": 23, - "weekday": true - }, - { - "start": 12, - "end": 22, - "weekday": false - } - ] + "hours": [] } ] }, @@ -66,18 +44,7 @@ { "name": "Noyes", "type": "fitness", - "hours": [ - { - "start": 7, - "end": 23, - "weekday": true - }, - { - "start": 14, - "end": 22, - "weekday": false - } - ] + "hours": [] } ] }, @@ -91,43 +58,16 @@ "image_url": "gyms/teagle.jpg'", "facilities": [ { - "name": "Teagle Up", + "name": "Teagle Upstairs", "type": "fitness", - "hours": [ - { - "start": 7, - "end": 22.75, - "weekday": true - }, - { - "start": 12, - "end": 17.5, - "weekday": false - } - ] + "hours": [] }, { - "name": "Teagle Down", + "name": "Teagle Downstairs", "type": "fitness", - "hours": [ - { - "start": 7, - "end": 8.5, - "weekday": true - }, - { - "start": 10, - "end": 22.75, - "weekday": true - }, - { - "start": 12, - "end": 17.5, - "weekday": false - } - ] + "hours": [] } ] } ] -} +} \ No newline at end of file diff --git a/src/constants.py b/src/constants.py index 4072dcc..b791b94 100644 --- a/src/constants.py +++ b/src/constants.py @@ -37,14 +37,9 @@ def create_gym_table(): facility["facility_type"] = FacilityType[facility["type"]] facilities.append(Facility(**facility)) - for i, open_hrs in enumerate(facility["hours"]): - hours_id_str = facility_id_str + str(i) - fitness_hours += create_times(uid_str=hours_id_str, facility_id=facility["id"], **open_hrs) for gym in gyms: db_session.merge(gym) for facility in facilities: db_session.merge(facility) - for hours in fitness_hours: - db_session.merge(hours) db_session.commit() diff --git a/src/models/capacity.py b/src/models/capacity.py index 6331eb6..009275b 100644 --- a/src/models/capacity.py +++ b/src/models/capacity.py @@ -1,7 +1,7 @@ from sqlalchemy import Column, ForeignKey, Integer, DateTime, Float from sqlalchemy.orm import backref, relationship -from database import Base +from src.database import Base """ Store counts for each Gym """ diff --git a/src/models/classes.py b/src/models/classes.py index 424a2c6..3e82890 100644 --- a/src/models/classes.py +++ b/src/models/classes.py @@ -1,6 +1,6 @@ import datetime -from ..database import Base +from src.database import Base from sqlalchemy import ( Table, Column, diff --git a/src/models/facility.py b/src/models/facility.py index e848c5a..72b10a9 100644 --- a/src/models/facility.py +++ b/src/models/facility.py @@ -3,8 +3,8 @@ import enum from sqlalchemy import Column, ForeignKey, String, Enum, Integer from sqlalchemy.orm import relationship -from database import Base -from models.capacity import Capacity +from src.database import Base +from src.models.capacity import Capacity diff --git a/src/models/openhours.py b/src/models/openhours.py index a20f199..e435341 100644 --- a/src/models/openhours.py +++ b/src/models/openhours.py @@ -1,5 +1,5 @@ from sqlalchemy import Column, ForeignKey, Integer, Float, String -from database import Base +from src.database import Base class OpenHours(Base): __tablename__ = "openhours" diff --git a/src/scrapers/gym_scraper.py b/src/scrapers/gym_scraper.py index 415b1e0..74102e9 100644 --- a/src/scrapers/gym_scraper.py +++ b/src/scrapers/gym_scraper.py @@ -1,52 +1,15 @@ import sys sys.path.append('..') -from database import db_session +from src.database import db_session from bs4 import BeautifulSoup import requests -from models.facility import Facility, FacilityType -from models.openhours import OpenHours -from models.gym import Gym +from src.models.facility import Facility, FacilityType +from src.models.openhours import OpenHours +from src.models.gym import Gym -# BASE_URL = 'https://scl.cornell.edu/recreation' BASE_URL_CENTERS = 'https://scl.cornell.edu/recreation/cornell-fitness-centers' -NEWMAN = 'https://scl.cornell.edu/recreation/facility/helen-newman-fitness-center' -result = requests.get(BASE_URL_CENTERS).text - -def create_fitcenter_object(h_ref): - page = requests.get(NEWMAN).text - soup = BeautifulSoup(page, 'lxml') - - box = soup.find('article', id='main-article', class_='primary') - facility_name = box.find('h1').get_text() - - facility = Facility(name=facility_name, facility_type=type.id) - db_session.add(facility) - db_session.commit() - print(facility_name) - return facility - -def scrape_fitcenters(): - centers = {} - page = requests.get(BASE_URL_CENTERS).text - soup = BeautifulSoup(page, 'lxml') - table = soup.find('table', class_='colored striped') - data = table.find_all('tr')[1:] - for row in data: - row_eles = row.find_all('td') - - week_times = row_eles[1].text.strip() - week_times = week_times.split('/') - - for time in week_times: - time = time.strip() - time = time.split('-') - time = [t.strip() for t in time] - - - - -def create_openhours(times_set, name, days): +def create_openhours(times_set, name, begin_day, end_day): for time in times_set: times = time.strip().split('-') times = [t.strip() for t in times] @@ -55,22 +18,21 @@ def create_openhours(times_set, name, days): if len(times) != 2: continue - am = times[0].lower().find('am') != -1 - stime_loc = times[0].lower().find('am') if am else times[0].lower().find('pm') - etime_loc = times[1].lower().find('am') if am else times[1].lower().find('pm') + am_st = times[0].lower().find('am') != -1 + am_e = times[1].lower().find('am') != -1 + stime_loc = times[0].lower().find('am') if am_st else times[0].lower().find('pm') + etime_loc = times[1].lower().find('am') if am_e else times[1].lower().find('pm') start = times[0][:stime_loc].strip() - start = start + 'am' if am else start + 'pm' + start = start + 'am' if am_st else start + 'pm' end = times[1][:etime_loc].strip() - end = end + 'am' if am else end + 'pm' + end = end + 'am' if am_e else end + 'pm' - #get facility id for specific fitness center - gym = db_session.query(Gym).filter(Gym.name == name).first() - facility = db_session.query(Facility).filter(Facility.gym_id == gym.id).first() + facility = db_session.query(Facility).filter(Facility.name == name).first() #put an open hour for each day: 1 = Monday, 2 = Tuesday, etc. - for i in range(1, 6): + for i in range(begin_day, end_day): try: hour = db_session.query(OpenHours).filter(OpenHours.facility_id==facility.id, OpenHours.day == i, OpenHours.start_time == start, OpenHours.end_time == end).first() assert hour is not None @@ -79,53 +41,71 @@ def create_openhours(times_set, name, days): db_session.add(hour) db_session.commit() -days_to_nums = { - 'monday': 1, - 'tuesday': 2, - 'wednesday': 3, - 'thursday': 4, - 'friday': 5, - 'saturday': 6, - 'sunday': 7, -} - -page = requests.get(BASE_URL_CENTERS).text -soup = BeautifulSoup(page, 'lxml') -table = soup.find('table', class_='colored striped') -data = table.find_all('tr') - -#finding the days - (for break hours this is necessary) -day_set = data[0].find_all('th')[1:] -day_set = [days.text.strip().split('-') for days in day_set] - -for i, days in enumerate(day_set): - if days[0].lower() == 'weekdays': - day_set[i] = [1, 6] - elif days[0].lower() == 'weekend': - day_set[i] = [6, 8] - else: - converted = [] - for day in days: - converted.append(days_to_nums[day.strip().lower()]) - if len(converted == 1): - converted.append(converted[0]+1) - day_set[i] = converted - -for days in day_set: - print(str(days)) - - - -# for row in data[1:]: -# row_eles = row.find_all('td') -# name = row_eles[0].text.strip() -# print(row_eles[1].text) -# print(row_eles[2].text) - -# for i in range(1, len(days)+1): -# times = row_eles[i].text.strip().split('/') - -# create_openhours(times, name, ) +def get_days(data): + days_to_nums = { + 'monday': 1, + 'tuesday': 2, + 'wednesday': 3, + 'thursday': 4, + 'friday': 5, + 'saturday': 6, + 'sunday': 7, + } + + + #finding the days - (for break hours this is necessary) + day_set = data[0].find_all('th')[1:] + day_set = [days.text.strip().split('-') for days in day_set] + + for i, days in enumerate(day_set): + if days[0].lower() == 'weekdays': + day_set[i] = [1, 6] + elif days[0].lower() == 'weekend': + day_set[i] = [6, 8] + else: + converted = [] + for day in days: + converted.append(days_to_nums[day.strip().lower()]) + if len(converted == 1): + converted.append(converted[0]) + converted[-1] += 1 + day_set[i] = converted + return day_set + +def create_times(day_set, data): + for row in data[1:]: + row_data = row.find_all('td') + name = row_data[0].text.strip() + row_data= row_data[1:] + + k = 0 + for i in range(len(row_data)): + colspan = 1 + if 'colspan' in row_data[i].attrs: + colspan = row_data[i].attrs['colspan'] + + begin_day = day_set[k][0] + for j in range(colspan): + end_day = day_set[k][1] + k += 1 + times = row_data[i].text.strip().split('/') + + create_openhours(times, name, begin_day, end_day) + +def scrape_times(): + page = requests.get(BASE_URL_CENTERS).text + soup = BeautifulSoup(page, 'lxml') + table = soup.find('table', class_='colored striped') + data = table.find_all('tr') + + d_set = get_days(data) + create_times(d_set, data) + + + + + + From 537dc735be21052f9a31de433aaf0e59b09a5cf7 Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Wed, 1 Nov 2023 17:45:11 -0400 Subject: [PATCH 26/39] changed some of activities --- src/models/activity.py | 2 +- c2c_scraper.py => src/scrapers/c2c_scraper.py | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename c2c_scraper.py => src/scrapers/c2c_scraper.py (100%) diff --git a/src/models/activity.py b/src/models/activity.py index 468b390..a5e9df6 100644 --- a/src/models/activity.py +++ b/src/models/activity.py @@ -1,4 +1,4 @@ -from sqlalchemy import Column, Float, String, Integer, ForeignKey +from sqlalchemy import Column, Float, String, Integer, ForeignKey, Table from sqlalchemy.orm import relationship from src.database import Base diff --git a/c2c_scraper.py b/src/scrapers/c2c_scraper.py similarity index 100% rename from c2c_scraper.py rename to src/scrapers/c2c_scraper.py From b01e8aef2441350e5bcc7d4bc599a42fdb0bfa19 Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Sun, 5 Nov 2023 12:22:04 -0500 Subject: [PATCH 27/39] class changes --- src/models/activity.py | 11 ++++++----- src/models/facility.py | 1 - src/schema.py | 10 ++++++++++ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/models/activity.py b/src/models/activity.py index 504291e..6054a0d 100644 --- a/src/models/activity.py +++ b/src/models/activity.py @@ -2,21 +2,22 @@ from sqlalchemy.orm import relationship from src.database import Base + association_table = Table( "association_table", Base.metadata, - Column("activity_id", ForeignKey("activity.id"), primary_key=True), - Column("facility_id", ForeignKey("facility.id"), primary_key=True) + Column("activity_id", ForeignKey("activity.id")), + Column("facility_id", ForeignKey("facility.id")) ) -def Activity(Base): +class Activity(Base): __tablename__ = 'activity' id = Column(Integer, primary_key = True) name = Column(String, nullable=False) activity_type = Column(Integer, ForeignKey('activitytype.id'), nullable=False) facilities = relationship("Facility", secondary=association_table, back_populates="activities") - prices = relationship('Price') + # prices = relationship('Price') image_url = Column(String(), nullable=False) def __init__(self, **kwargs): @@ -27,7 +28,7 @@ def __init__(self, **kwargs): self.image_url = kwargs.get('image_url') -def ActivityType(Base): +class ActivityType(Base): __tablename__ = 'activitytype' id = Column(Integer, primary_key=True) diff --git a/src/models/facility.py b/src/models/facility.py index 2b9cac8..2598f3e 100644 --- a/src/models/facility.py +++ b/src/models/facility.py @@ -7,7 +7,6 @@ from src.models.capacity import Capacity from src.models.activity import association_table - class FacilityType(enum.Enum): fitness = 0 diff --git a/src/schema.py b/src/schema.py index c7dffc1..92dda4e 100644 --- a/src/schema.py +++ b/src/schema.py @@ -5,6 +5,7 @@ from src.models.facility import Facility as FacilityModel from src.models.gym import Gym as GymModel from src.models.openhours import OpenHours as OpenHoursModel +from src.models.activity import Activity as ActivityModel # MARK: - Gym @@ -28,6 +29,7 @@ class Meta: open_hours = graphene.List(lambda: OpenHours, name=graphene.String()) capacity = graphene.Field(lambda: Capacity) + activities = graphene.List(lambda: Activity) def resolve_open_hours(self, info): query = OpenHours.get_query(info=info).filter(OpenHoursModel.facility_id == self.id) @@ -38,6 +40,7 @@ def resolve_capacity(self, info): return query + # MARK: - Open Hours class OpenHours(SQLAlchemyObjectType): @@ -51,6 +54,13 @@ class Capacity(SQLAlchemyObjectType): class Meta: model = CapacityModel +# MARK: - Activity +class Activity(SQLAlchemyObjectType): + class Meta: + model = ActivityModel + + facilities = graphene.List(lambda: Facility) + # MARK: - Query From 10ae6f3e9e4d5808e3a3e247f1a145e878d0cb2e Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Wed, 15 Nov 2023 21:32:17 -0500 Subject: [PATCH 28/39] bug fixes on the scraper --- schema.graphql | 8 ++++---- src/appdev-py | 1 - src/models/classes.py | 4 ++-- src/models/openhours.py | 4 ++-- src/scrapers/gym_scraper.py | 37 ++++++++++++++++++++++++++----------- src/scrapers/scraper.py | 6 ++++-- 6 files changed, 38 insertions(+), 22 deletions(-) delete mode 160000 src/appdev-py diff --git a/schema.graphql b/schema.graphql index 3747d29..a925801 100644 --- a/schema.graphql +++ b/schema.graphql @@ -25,8 +25,8 @@ type ClassInstance { instructor: String! isCanceled: Boolean! isVirtual: Boolean! - startTime: DateTime! - endTime: DateTime! + startTime: DateTime + endTime: DateTime class_: Class gym: Gym } @@ -64,8 +64,8 @@ type OpenHours { id: ID! facilityId: Int! day: Int! - startTime: String! - endTime: String! + startTime: String + endTime: String } type Query { diff --git a/src/appdev-py b/src/appdev-py deleted file mode 160000 index fffe58a..0000000 --- a/src/appdev-py +++ /dev/null @@ -1 +0,0 @@ -Subproject commit fffe58a01ba5bc00493213e2baa00a6a9e393280 diff --git a/src/models/classes.py b/src/models/classes.py index 0ebc4f6..60e97be 100644 --- a/src/models/classes.py +++ b/src/models/classes.py @@ -43,8 +43,8 @@ class ClassInstance(Base): instructor = Column(String(), nullable=False) isCanceled = Column(Boolean(), nullable=False, default=False) isVirtual = Column(Boolean(), nullable=False, default=False) - start_time = Column(DateTime(), nullable=False) - end_time = Column(DateTime(), nullable=False) + start_time = Column(DateTime(), nullable=True) + end_time = Column(DateTime(), nullable=True) class_ = relationship("Class", back_populates="gyms") gym = relationship("Gym", back_populates="classes") diff --git a/src/models/openhours.py b/src/models/openhours.py index 76d5a54..a76f2bd 100644 --- a/src/models/openhours.py +++ b/src/models/openhours.py @@ -15,8 +15,8 @@ class OpenHours(Base): id = Column(Integer, primary_key=True) facility_id = Column(Integer, ForeignKey("facility.id"), nullable=False) day = Column(Integer, nullable=False) # 0=Monday, 5=Weekend - start_time = Column(Time(), nullable=False) - end_time = Column(Time(), nullable=False) + start_time = Column(Time(), nullable=True) + end_time = Column(Time(), nullable=True) # TODO: - Handle restrictions and special hours restrictions = relationship("Restrictions", secondary=openhours_restrictions, back_populates="openhours") # special_hours = Column(Boolean, nullable=False) diff --git a/src/scrapers/gym_scraper.py b/src/scrapers/gym_scraper.py index 74102e9..9bdcb25 100644 --- a/src/scrapers/gym_scraper.py +++ b/src/scrapers/gym_scraper.py @@ -6,6 +6,7 @@ from src.models.facility import Facility, FacilityType from src.models.openhours import OpenHours from src.models.gym import Gym +from datetime import datetime as dt BASE_URL_CENTERS = 'https://scl.cornell.edu/recreation/cornell-fitness-centers' @@ -24,32 +25,46 @@ def create_openhours(times_set, name, begin_day, end_day): etime_loc = times[1].lower().find('am') if am_e else times[1].lower().find('pm') start = times[0][:stime_loc].strip() - start = start + 'am' if am_st else start + 'pm' + start = start + 'AM' if am_st else start + 'PM' end = times[1][:etime_loc].strip() - end = end + 'am' if am_e else end + 'pm' + end = end + 'AM' if am_e else end + 'PM' + facility = db_session.query(Facility).filter(Facility.name == name).first() #put an open hour for each day: 1 = Monday, 2 = Tuesday, etc. for i in range(begin_day, end_day): + # if int(start[0]) < 10: + # start = '0' + start + # if int(end[0]) < 10: + # end = '0' + end + if ':' in start: + st_obj = dt.strptime(start, "%I:%M%p") + else: + st_obj = dt.strptime(start, "%I%p") + if ':' in end: + end_obj = dt.strptime(end, "%I:%M%p") + else: + end_obj = dt.strptime(end, "%I%p") try: - hour = db_session.query(OpenHours).filter(OpenHours.facility_id==facility.id, OpenHours.day == i, OpenHours.start_time == start, OpenHours.end_time == end).first() + hour = db_session.query(OpenHours).filter(OpenHours.facility_id==facility.id, OpenHours.day == i, OpenHours.start_time == st_obj.time(), OpenHours.end_time == end_obj.time()).first() assert hour is not None except AssertionError: - hour = OpenHours(facility_id=facility.id, day=i, start_time=start, end_time=end) + + hour = OpenHours(facility_id=facility.id, day=i, start_time=st_obj.time(), end_time=end_obj.time(), restrictions=[]) db_session.add(hour) db_session.commit() def get_days(data): days_to_nums = { - 'monday': 1, - 'tuesday': 2, - 'wednesday': 3, - 'thursday': 4, - 'friday': 5, - 'saturday': 6, - 'sunday': 7, + 'monday': 0, + 'tuesday': 1, + 'wednesday': 2, + 'thursday': 3, + 'friday': 4, + 'saturday': 5, + 'sunday': 6, } diff --git a/src/scrapers/scraper.py b/src/scrapers/scraper.py index 947b515..097b2f5 100644 --- a/src/scrapers/scraper.py +++ b/src/scrapers/scraper.py @@ -86,16 +86,18 @@ def scrape_classes(num_pages): # special handling for time (cancelled) time_str = row_elems[3].string.replace("\n", "").strip() - if time_str != "" and "Canceled" not in time_str: + if time_str != "" and time_str != 'Canceled': class_instance.is_canceled = False time_strs = time_str.split(" - ") start_time_string = time_strs[0].strip() + # print(start_time_string) end_time_string = time_strs[1].strip() + # print(end_time_string) class_instance.start_time = datetime.strptime(f"{date_string} {start_time_string}", "%m/%d/%Y %I:%M%p") class_instance.end_time = datetime.strptime(f"{date_string} {end_time_string}", "%m/%d/%Y %I:%M%p") else: - class_instance.is_canceled = True + class_instance.isCanceled = True try: class_instance.instructor = row_elems[4].a.string From 2ec86b9882d5a938c95d3551fa33a2b864c8f019 Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Wed, 15 Nov 2023 22:43:57 -0500 Subject: [PATCH 29/39] fixing scraping hours --- src/constants.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/constants.py b/src/constants.py index 8d6a846..4153cc8 100644 --- a/src/constants.py +++ b/src/constants.py @@ -49,6 +49,6 @@ def create_gym_table(): db_session.merge(gym) for facility in facilities: db_session.merge(facility) - for hours in fitness_hours: - db_session.merge(hours) + # for hours in fitness_hours: + # db_session.merge(hours) db_session.commit() From 0c14694e4c837e4ee80c20b3358f7871cbb0d687 Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Sat, 18 Nov 2023 23:59:12 -0500 Subject: [PATCH 30/39] fixing activities --- schema.graphql | 10 ++++++++++ src/models/facility.py | 1 + src/schema.py | 3 ++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/schema.graphql b/schema.graphql index a925801..2a71870 100644 --- a/schema.graphql +++ b/schema.graphql @@ -2,6 +2,14 @@ schema { query: Query } +type Activity { + id: ID! + name: String! + activityType: Int! + imageUrl: String! + facilities: [Facility] +} + type Capacity { id: ID! facilityId: Int! @@ -40,7 +48,9 @@ type Facility { facilityType: FacilityType! openHours(name: String): [OpenHours] capacities: [Capacity] + activities: [Activity] capacity: Capacity + activity: Activity } enum FacilityType { diff --git a/src/models/facility.py b/src/models/facility.py index 4242ab7..3f91da3 100644 --- a/src/models/facility.py +++ b/src/models/facility.py @@ -4,6 +4,7 @@ from sqlalchemy import Column, ForeignKey, String, Enum, Integer from sqlalchemy.orm import relationship from src.database import Base +from src.models.activity import association_table from src.models.capacity import Capacity diff --git a/src/schema.py b/src/schema.py index 6cf999a..688765c 100644 --- a/src/schema.py +++ b/src/schema.py @@ -7,7 +7,7 @@ from src.models.openhours import OpenHours as OpenHoursModel from src.models.classes import Class as ClassModel from src.models.classes import ClassInstance as ClassInstanceModel - +from src.models.activity import Activity as ActivityModel # MARK: - Gym @@ -32,6 +32,7 @@ class Meta: open_hours = graphene.List(lambda: OpenHours, name=graphene.String()) capacity = graphene.Field(lambda: Capacity) + activity = graphene.Field(lambda: Activity) def resolve_open_hours(self, info): query = OpenHours.get_query(info=info).filter(OpenHoursModel.facility_id == self.id) From 66643226297f09559f5be56e964ca01a06e8576f Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Sun, 19 Nov 2023 00:26:31 -0500 Subject: [PATCH 31/39] completed fixed activities --- schema.graphql | 2 -- src/schema.py | 11 ++++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/schema.graphql b/schema.graphql index 2a71870..7f4f7c3 100644 --- a/schema.graphql +++ b/schema.graphql @@ -49,8 +49,6 @@ type Facility { openHours(name: String): [OpenHours] capacities: [Capacity] activities: [Activity] - capacity: Capacity - activity: Activity } enum FacilityType { diff --git a/src/schema.py b/src/schema.py index 688765c..0038799 100644 --- a/src/schema.py +++ b/src/schema.py @@ -31,8 +31,8 @@ class Meta: model = FacilityModel open_hours = graphene.List(lambda: OpenHours, name=graphene.String()) - capacity = graphene.Field(lambda: Capacity) - activity = graphene.Field(lambda: Activity) + capacities = graphene.List(lambda: Capacity) + activities = graphene.List(lambda: Activity) def resolve_open_hours(self, info): query = OpenHours.get_query(info=info).filter(OpenHoursModel.facility_id == self.id) @@ -79,10 +79,11 @@ class Meta: # MARK: - Activity class Activity(SQLAlchemyObjectType): - class Meta: - model = ActivityModel + class Meta: + model = ActivityModel + + facilities = graphene.List(lambda: Facility) - facilities = graphene.List(lambda: Facility) # MARK: - Query From 92a1cf590d59fca8b9198336f5b26adc4f3b31aa Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Sun, 19 Nov 2023 02:26:52 -0500 Subject: [PATCH 32/39] modified gym_scraper to accomodate special_hours --- schema.graphql | 1 + src/models/openhours.py | 8 +++--- src/scrapers/gym_scraper.py | 53 +++++++++++++------------------------ src/scrapers/scraper.py | 6 ++--- 4 files changed, 25 insertions(+), 43 deletions(-) diff --git a/schema.graphql b/schema.graphql index 7f4f7c3..1d128c8 100644 --- a/schema.graphql +++ b/schema.graphql @@ -74,6 +74,7 @@ type OpenHours { day: Int! startTime: String endTime: String + specialHours: Boolean! } type Query { diff --git a/src/models/openhours.py b/src/models/openhours.py index a76f2bd..2391e7c 100644 --- a/src/models/openhours.py +++ b/src/models/openhours.py @@ -1,5 +1,5 @@ import enum -from sqlalchemy import Column, ForeignKey, Integer, Float, String, Time, String, Table, Enum +from sqlalchemy import Column, ForeignKey, Integer, Float, String, Time, String, Table, Enum, Boolean from sqlalchemy.orm import backref, relationship from src.database import Base @@ -19,7 +19,7 @@ class OpenHours(Base): end_time = Column(Time(), nullable=True) # TODO: - Handle restrictions and special hours restrictions = relationship("Restrictions", secondary=openhours_restrictions, back_populates="openhours") - # special_hours = Column(Boolean, nullable=False) + special_hours = Column(Boolean(), nullable=False) def __init__(self, **kwargs): self.id = kwargs.get("id") @@ -29,7 +29,7 @@ def __init__(self, **kwargs): self.end_time = kwargs.get("end_time") # TODO: - Handle restrictions and special hours self.restrictions = kwargs.get("restrictions") - # self.special_hours = kwargs.get("special_hours") + self.special_hours = kwargs.get("special_hours") def serialize(self): return { @@ -40,7 +40,7 @@ def serialize(self): "end_time": self.end_time, # TODO: - Handle restrictions and special hours "restrictions": self.restrictions, - # "special_hours": self.special_hours + "special_hours": self.special_hours } class RestrictionEnum(enum.Enum): diff --git a/src/scrapers/gym_scraper.py b/src/scrapers/gym_scraper.py index 9bdcb25..e96911f 100644 --- a/src/scrapers/gym_scraper.py +++ b/src/scrapers/gym_scraper.py @@ -10,7 +10,7 @@ BASE_URL_CENTERS = 'https://scl.cornell.edu/recreation/cornell-fitness-centers' -def create_openhours(times_set, name, begin_day, end_day): +def create_openhours(times_set, name, begin_day, end_day, special): for time in times_set: times = time.strip().split('-') times = [t.strip() for t in times] @@ -33,12 +33,8 @@ def create_openhours(times_set, name, begin_day, end_day): facility = db_session.query(Facility).filter(Facility.name == name).first() - #put an open hour for each day: 1 = Monday, 2 = Tuesday, etc. + #put an open hour for each day: 0 = Monday, 1 = Tuesday, etc. for i in range(begin_day, end_day): - # if int(start[0]) < 10: - # start = '0' + start - # if int(end[0]) < 10: - # end = '0' + end if ':' in start: st_obj = dt.strptime(start, "%I:%M%p") else: @@ -48,11 +44,10 @@ def create_openhours(times_set, name, begin_day, end_day): else: end_obj = dt.strptime(end, "%I%p") try: - hour = db_session.query(OpenHours).filter(OpenHours.facility_id==facility.id, OpenHours.day == i, OpenHours.start_time == st_obj.time(), OpenHours.end_time == end_obj.time()).first() + hour = db_session.query(OpenHours).filter(OpenHours.facility_id==facility.id, OpenHours.day == i, OpenHours.start_time == st_obj.time(), OpenHours.end_time == end_obj.time(), OpenHours.special_hours == special).first() assert hour is not None except AssertionError: - - hour = OpenHours(facility_id=facility.id, day=i, start_time=st_obj.time(), end_time=end_obj.time(), restrictions=[]) + hour = OpenHours(facility_id=facility.id, day=i, start_time=st_obj.time(), end_time=end_obj.time(), restrictions=[], special_hours=special) db_session.add(hour) db_session.commit() @@ -81,13 +76,13 @@ def get_days(data): converted = [] for day in days: converted.append(days_to_nums[day.strip().lower()]) - if len(converted == 1): + if len(converted) == 1: converted.append(converted[0]) converted[-1] += 1 day_set[i] = converted return day_set -def create_times(day_set, data): +def create_times(day_set, data, special): for row in data[1:]: row_data = row.find_all('td') name = row_data[0].text.strip() @@ -97,7 +92,7 @@ def create_times(day_set, data): for i in range(len(row_data)): colspan = 1 if 'colspan' in row_data[i].attrs: - colspan = row_data[i].attrs['colspan'] + colspan = int(row_data[i].attrs['colspan']) begin_day = day_set[k][0] for j in range(colspan): @@ -105,30 +100,18 @@ def create_times(day_set, data): k += 1 times = row_data[i].text.strip().split('/') - create_openhours(times, name, begin_day, end_day) + create_openhours(times, name, begin_day, end_day, special) def scrape_times(): page = requests.get(BASE_URL_CENTERS).text soup = BeautifulSoup(page, 'lxml') - table = soup.find('table', class_='colored striped') - data = table.find_all('tr') - - d_set = get_days(data) - create_times(d_set, data) - - - - - - - - - - - - - - - - - + tables = soup.find_all('table', class_='colored striped') + data_list = [] + for table in tables: + data_list.append(table.find_all('tr')) + + for i in range(len(data_list)): + special = i != 0 + data = data_list[i] + d_set = get_days(data) + create_times(d_set, data, special) diff --git a/src/scrapers/scraper.py b/src/scrapers/scraper.py index 097b2f5..79843df 100644 --- a/src/scrapers/scraper.py +++ b/src/scrapers/scraper.py @@ -90,9 +90,7 @@ def scrape_classes(num_pages): class_instance.is_canceled = False time_strs = time_str.split(" - ") start_time_string = time_strs[0].strip() - # print(start_time_string) end_time_string = time_strs[1].strip() - # print(end_time_string) class_instance.start_time = datetime.strptime(f"{date_string} {start_time_string}", "%m/%d/%Y %I:%M%p") class_instance.end_time = datetime.strptime(f"{date_string} {end_time_string}", "%m/%d/%Y %I:%M%p") @@ -171,7 +169,7 @@ def scrape_pool_hours(): time_text = time.strip() try: if "Closed" in time_text: - openhour = OpenHours(**{"facility_id": pool.id, "day": i, "end_time": dt.time(0), "start_time": dt.time(0), "restrictions": []}) + openhour = OpenHours(**{"facility_id": pool.id, "day": i, "end_time": dt.time(0), "start_time": dt.time(0), "restrictions": [], "special_hours": False}) closed_obj = db_session.query(Restrictions).filter_by(restriction='closed').first() openhour.restrictions.append(closed_obj) db_session.add(openhour) @@ -191,7 +189,7 @@ def scrape_pool_hours(): end_time = datetime.strptime(end_time_string, "%I:%M%p").time() openhour = OpenHours( - **{"facility_id": pool.id, "day": i, "end_time": end_time, "start_time": start_time, "restrictions": []} + **{"facility_id": pool.id, "day": i, "end_time": end_time, "start_time": start_time, "restrictions": [], "special_hours": False} ) if women_only: women_only_obj = db_session.query(Restrictions).filter_by(restriction='women_only').first() From 01f7405dca18b99cfd0e4a322e136329a854b4c7 Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Tue, 13 Feb 2024 12:49:26 -0500 Subject: [PATCH 33/39] Scraped equipment and added it to the Schema --- app.py | 2 + schema.graphql | 24 ++++++++ src/__init__.py | 0 src/models/equipment.py | 40 +++++++++++++ src/models/facility.py | 4 ++ src/models/gym.py | 1 + src/schema.py | 21 +++++-- src/scrapers/equipment_scraper.py | 97 +++++++++++++++++++++++++++++++ src/utils/constants.py | 20 +++++++ 9 files changed, 205 insertions(+), 4 deletions(-) create mode 100644 src/__init__.py create mode 100644 src/models/equipment.py create mode 100644 src/scrapers/equipment_scraper.py diff --git a/app.py b/app.py index 1330ae5..71c96b8 100644 --- a/app.py +++ b/app.py @@ -10,6 +10,7 @@ from src.scrapers.reg_hours_scraper import fetch_reg_building, fetch_reg_facility from src.scrapers.scraper_helpers import clean_past_hours from src.scrapers.sp_hours_scraper import fetch_sp_facility +from src.scrapers.equipment_scraper import scrape_equipment from src.utils.utils import create_gym_table @@ -63,6 +64,7 @@ def scrape_capacities(): create_gym_table() scrape_hours() scrape_capacities() +scrape_equipment() # Create schema.graphql with open("schema.graphql", "w+") as schema_file: diff --git a/schema.graphql b/schema.graphql index b7c0ee7..5a0f6eb 100644 --- a/schema.graphql +++ b/schema.graphql @@ -2,6 +2,10 @@ schema { query: Query } +enum AccessibilityType { + WHEELCHAIR +} + type Amenity { id: ID! gymId: Int! @@ -29,6 +33,25 @@ enum CourtType { BADMINTON } +type Equipment { + id: ID! + name: String! + equipmentType: EquipmentType! + facilityId: Int! + quantity: Int + accessibility: AccessibilityType +} + +enum EquipmentType { + CARDIO + RACKS_AND_BENCHES + SELECTORIZED + MULTI_CABLE + FREE_WEIGHTS + MISCELLANEOUS + PLATE_LOADED +} + type Facility { id: ID! facilityType: FacilityType! @@ -36,6 +59,7 @@ type Facility { name: String! capacity: Capacity hours: [OpenHours] + equipment: [Equipment] } enum FacilityType { diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/models/equipment.py b/src/models/equipment.py new file mode 100644 index 0000000..e56712d --- /dev/null +++ b/src/models/equipment.py @@ -0,0 +1,40 @@ +import enum +from sqlalchemy import Column, String, Enum, Integer, ForeignKey +from sqlalchemy.orm import relationship +from src.database import Base + +class EquipmentType(enum.Enum): + + cardio = 0 + racks_and_benches = 1 + selectorized = 2 + multi_cable = 3 + free_weights = 4 + miscellaneous = 5 + plate_loaded = 6 + + +class AccessibilityType(enum.Enum): + + wheelchair = 0 + +class Equipment(Base): + + __tablename__ = "equipment" + + id = Column(Integer, primary_key=True) + name = Column(String, nullable=False) + equipment_type = Column(Enum(EquipmentType), nullable=False) + facility_id = Column(Integer, ForeignKey("facility.id"), nullable=False) + quantity = Column(Integer, nullable=True) + accessibility = Column(Enum(AccessibilityType), nullable=True) + + def __init__(self, **kwargs): + self.id = kwargs.get("id") + self.name = kwargs.get("name") + self.equipment_type = kwargs.get("equipment_type") + self.facility_id = kwargs.get("facility_id") + self.quantity = kwargs.get("quantity") + self.accessibility = kwargs.get("accessibility") + + diff --git a/src/models/facility.py b/src/models/facility.py index 0506f77..5e1686d 100644 --- a/src/models/facility.py +++ b/src/models/facility.py @@ -2,6 +2,9 @@ from sqlalchemy import Column, String, Enum, Integer, ForeignKey from sqlalchemy.orm import relationship from src.database import Base +from src.models.openhours import OpenHours +from src.models.equipment import Equipment +from src.models.capacity import Capacity class FacilityType(enum.Enum): @@ -36,6 +39,7 @@ class Facility(Base): gym_id = Column(Integer, ForeignKey("gym.id"), nullable=False) hours = relationship("OpenHours") name = Column(String, nullable=False) + equipment = relationship("Equipment") def __init__(self, **kwargs): self.id = kwargs.get("id") diff --git a/src/models/gym.py b/src/models/gym.py index 6ce9a12..20de79a 100644 --- a/src/models/gym.py +++ b/src/models/gym.py @@ -1,6 +1,7 @@ from sqlalchemy import Column, Float, String, Integer from sqlalchemy.orm import relationship from src.database import Base +from src.models.openhours import OpenHours class Gym(Base): diff --git a/src/schema.py b/src/schema.py index b83c6ff..fe63f09 100644 --- a/src/schema.py +++ b/src/schema.py @@ -5,6 +5,7 @@ from src.models.gym import Gym as GymModel from src.models.openhours import OpenHours as OpenHoursModel from src.models.amenity import Amenity as AmenityModel +from src.models.equipment import Equipment as EquipmentModel # MARK: - Gym @@ -40,6 +41,7 @@ class Meta: capacity = graphene.Field(lambda: Capacity) hours = graphene.List(lambda: OpenHours) + equipment = graphene.List(lambda: Equipment) def resolve_capacity(self, info): query = ( @@ -53,6 +55,10 @@ def resolve_capacity(self, info): def resolve_hours(self, info): query = OpenHours.get_query(info=info).filter(OpenHoursModel.facility_id == self.id) return query + + def resolve_equipment(self, info): + query = Equipment.get_query(info=info).filter(EquipmentModel.facility_id == self.id) + return query @@ -63,6 +69,13 @@ class OpenHours(SQLAlchemyObjectType): class Meta: model = OpenHoursModel +# MARK: - Equipment + + +class Equipment(SQLAlchemyObjectType): + class Meta: + model = EquipmentModel + # MARK: - Amenity @@ -80,11 +93,11 @@ class Meta: model = CapacityModel # MARK: - Activity -class Activity(SQLAlchemyObjectType): - class Meta: - model = ActivityModel +# class Activity(SQLAlchemyObjectType): +# class Meta: +# model = ActivityModel - facilities = graphene.List(lambda: Facility) +# facilities = graphene.List(lambda: Facility) diff --git a/src/scrapers/equipment_scraper.py b/src/scrapers/equipment_scraper.py new file mode 100644 index 0000000..24c1966 --- /dev/null +++ b/src/scrapers/equipment_scraper.py @@ -0,0 +1,97 @@ +from bs4 import BeautifulSoup +import requests +from src.database import db_session +from src.models.equipment import Equipment, EquipmentType, AccessibilityType +from src.utils.utils import get_facility_id +from src.utils.constants import ( + HNH_DETAILS, + NOYES_DETAILS, + TEAGLE_DOWN_DETAILS, + TEAGLE_UP_DETAILS, + MORRISON_DETAILS +) + +equip_pages = [HNH_DETAILS, NOYES_DETAILS, TEAGLE_DOWN_DETAILS, TEAGLE_UP_DETAILS, MORRISON_DETAILS] + +def categorize_equip(category): + if "cardio" in category.lower(): + return EquipmentType.cardio + if "racks" in category.lower() or "benches" in category.lower(): + return EquipmentType.racks_and_benches + if "selectorized" in category.lower(): + return EquipmentType.selectorized + if "multi-cable" in category.lower(): + return EquipmentType.multi_cable + if "free weights" in category.lower(): + return EquipmentType.free_weights + if "miscellaneous" in category.lower(): + return EquipmentType.miscellaneous + if "plate" in category.lower(): + return EquipmentType.plate_loaded + return -1 + + +def create_equip(category, equip, fit_center_id, fit_center): + """ + Create equipment from a list of equipment. + """ + equip_list = equip.find_all('li') + equip_db_objs = [] + for equip in equip_list: + if "precor ellipticals" in equip.text.lower() and fit_center == "Teagle Up Fitness Center": + equip_obj = "Precor Ellipticals" + num_objs = 10 + else: + equip_obj = equip.text.split(' ') + num_objs = 0 + if equip_obj[0].isnumeric(): + num_objs = int(equip_obj[0]) + equip_obj = equip_obj[1:] + equip_obj = ' '.join(equip_obj) + + num_objs = None if num_objs == 0 else num_objs + accessibility_option = None if "wheelchair" not in equip_obj else 1 + equip_type = categorize_equip(category) + + try: + existing_equip = db_session.query(Equipment).filter(Equipment.name==equip_obj, Equipment.equipment_type==equip_type, Equipment.facility_id==fit_center_id).first() + assert existing_equip is not None + except: + equip_db_obj = Equipment( + name=equip_obj, + equipment_type=equip_type, + facility_id=fit_center_id, + quantity=num_objs, + accessibility = AccessibilityType.wheelchair if accessibility_option else None + ) + equip_db_objs.append(equip_db_obj) + db_session.add_all(equip_db_objs) + db_session.commit() + + + +def process_equip_page(page, fit_center): + """ + Process equipment page. + """ + + soup = BeautifulSoup(requests.get(page).content, 'lxml') + table = soup.find('table') + body = table.find_all('tr') + fit_center_id = get_facility_id(fit_center) + for even_row in range(0, len(body), 2): + categories = body[even_row].find_all('th') + equip = body[even_row + 1].find_all('td') + if categories[0].text: + create_equip(categories[0].text, equip[0], fit_center_id, fit_center) + if categories[1].text: + create_equip(categories[1].text, equip[1], fit_center_id, fit_center) + +def scrape_equipment(): + process_equip_page(HNH_DETAILS, "HNH Fitness Center") + process_equip_page(NOYES_DETAILS, "Noyes Fitness Center") + process_equip_page(TEAGLE_DOWN_DETAILS, "Teagle Down Fitness Center") + process_equip_page(TEAGLE_UP_DETAILS, "Teagle Up Fitness Center") + process_equip_page(MORRISON_DETAILS, "Morrison Fitness Center") + + diff --git a/src/utils/constants.py b/src/utils/constants.py index ce14c95..a3166ea 100644 --- a/src/utils/constants.py +++ b/src/utils/constants.py @@ -36,6 +36,12 @@ # Eastern Timezone EASTERN_TIMEZONE = "America/New_York" +# The path for general gym hours +GYM_HOUR_BASE_URL = "https://scl.cornell.edu/recreation/cornell-fitness-centers" + +# The path for Helen Newman Fitness Center details +HNH_DETAILS = "https://scl.cornell.edu/recreation/facility/helen-newman-fitness-center" + # Marker in sheets for alternating between badminton and volleyball (HNH Fridays) MARKER_ALT = "(ALT)" @@ -72,6 +78,12 @@ # Marker in sheets for women pool MARKER_WOMEN = "(W)" +# The path for Morrison Fitness Center details +MORRISON_DETAILS = "https://scl.cornell.edu/recreation/facility/toni-morrison-fitness-center" + +# The path for Noyes Fitness Center details +NOYES_DETAILS = "https://scl.cornell.edu/recreation/facility/noyes-fitness-center" + # The number of seconds in a day SECONDS_IN_DAY = 86400 @@ -96,3 +108,11 @@ # Worksheet name for special facility hours SHEET_SP_FACILITY = "[SP] Facility Hours" + +# The path for Teagle Down Fitness Center details +TEAGLE_DOWN_DETAILS = "https://scl.cornell.edu/recreation/facility/teagle-downstairs" + +# The path for Teagle Up Fitness Center details +TEAGLE_UP_DETAILS = "https://scl.cornell.edu/recreation/facility/teagle-upstairs" + + From 1b6ad7c22051499b62d3bb10a9256c8f880679bc Mon Sep 17 00:00:00 2001 From: Kidus Zegeye <51487468+kidzegeye@users.noreply.github.com> Date: Wed, 14 Feb 2024 12:32:12 -0500 Subject: [PATCH 34/39] Upgrade python version for the test workflow --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7badd9b..9648f36 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/checkout@v1 - uses: actions/setup-python@v1 with: - python-version: 3.8 + python-version: 3.9 - name: install and test run: | sudo apt-get update From d7c0c0df9f1f89964cada379f5c748473f1f660f Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Wed, 28 Feb 2024 17:22:41 -0500 Subject: [PATCH 35/39] added back classes and class scraper --- app.py | 2 + schema.graphql | 24 +++++ src/models/classes.py | 90 ++++++++++++++++ src/models/gym.py | 2 + src/schema.py | 12 +++ src/scrapers/class_scraper.py | 190 ++++++++++++++++++++++++++++++++++ src/utils/constants.py | 3 + 7 files changed, 323 insertions(+) create mode 100644 src/models/classes.py create mode 100644 src/scrapers/class_scraper.py diff --git a/app.py b/app.py index 71c96b8..3033203 100644 --- a/app.py +++ b/app.py @@ -11,6 +11,7 @@ from src.scrapers.scraper_helpers import clean_past_hours from src.scrapers.sp_hours_scraper import fetch_sp_facility from src.scrapers.equipment_scraper import scrape_equipment +from src.scrapers.class_scraper import scrape_classes from src.utils.utils import create_gym_table @@ -65,6 +66,7 @@ def scrape_capacities(): scrape_hours() scrape_capacities() scrape_equipment() +scrape_classes() # Create schema.graphql with open("schema.graphql", "w+") as schema_file: diff --git a/schema.graphql b/schema.graphql index 5a0f6eb..718052d 100644 --- a/schema.graphql +++ b/schema.graphql @@ -27,12 +27,35 @@ type Capacity { updated: Int! } +type Class { + id: ID! + name: String! + description: String! + gyms: [ClassInstance] +} + +type ClassInstance { + id: ID! + gymId: Int + classId: Int! + location: String! + instructor: String! + isCanceled: Boolean! + isVirtual: Boolean! + startTime: DateTime + endTime: DateTime + class_: Class + gym: Gym +} + enum CourtType { BASKETBALL VOLLEYBALL BADMINTON } +scalar DateTime + type Equipment { id: ID! name: String! @@ -79,6 +102,7 @@ type Gym { amenities: [Amenity] facilities: [Facility] hours: [OpenHours] + classes: [ClassInstance] } type OpenHours { diff --git a/src/models/classes.py b/src/models/classes.py new file mode 100644 index 0000000..f425509 --- /dev/null +++ b/src/models/classes.py @@ -0,0 +1,90 @@ +import datetime +from src.database import Base +from sqlalchemy import ( + Table, + Column, + DateTime, + ForeignKey, + Integer, + Float, + String, + Boolean, + func, +) +from sqlalchemy.orm import backref, relationship + +classes_to_gyms = Table( + "classes_to_gyms", + Base.metadata, + Column("id", Integer(), primary_key=True), + Column("gym_id", ForeignKey("gym.id")), + Column("class_id", ForeignKey("class.id")), + Column("location", String()), + Column("instructor", String()), + Column("isCancelled", Boolean()), + Column("start_time", DateTime()), + Column("end_time", DateTime()), +) + + +class Class(Base): + __tablename__ = "class" + + id = Column(Integer, primary_key=True) + name = Column(String(), nullable=False) + description = Column(String(), nullable=False) + gyms = relationship("ClassInstance", back_populates="class_") + + def __init__(self, **kwargs): + self.id = kwargs.get("id") + self.name = kwargs.get("name") + self.description = kwargs.get("description") + + def serialize(self): + return { + "id": self.id, + "name": self.name, + "description": self.description, + } + + +class ClassInstance(Base): + __tablename__ = "class_instance" + + id = Column(Integer, primary_key=True) + gym_id = Column(Integer, ForeignKey("gym.id"), nullable=True) + class_id = Column(Integer, ForeignKey("class.id"), nullable=False) + location = Column(String(), nullable=False) + instructor = Column(String(), nullable=False) + isCanceled = Column(Boolean(), nullable=False, default=False) + isVirtual = Column(Boolean(), nullable=False, default=False) + start_time = Column(DateTime(), nullable=True) + end_time = Column(DateTime(), nullable=True) + class_ = relationship("Class", back_populates="gyms") + gym = relationship("Gym", back_populates="classes") + + def __init__(self, **kwargs): + self.id = kwargs.get("id") + self.gym_id = kwargs.get("gym_id") + self.class_id = kwargs.get("class_id") + self.location = kwargs.get("location") + self.instructor = kwargs.get("instructor") + self.isCanceled = kwargs.get("isCanceled") + self.isVirtual = kwargs.get("isVirtual") + self.start_time = kwargs.get("start_time") + self.end_time = kwargs.get("end_time") + + def serialize(self): + return { + "id": self.id, + "gym_id": self.gym_id, + "class_id": self.class_id, + "location": self.location, + "instructor": self.instructor, + "isCanceled": self.isCanceled, + "isVirtual": self.isVirtual, + "start_time": self.start_time, + "end_time": self.end_time, + } + + diff --git a/src/models/gym.py b/src/models/gym.py index 20de79a..734cc84 100644 --- a/src/models/gym.py +++ b/src/models/gym.py @@ -2,6 +2,7 @@ from sqlalchemy.orm import relationship from src.database import Base from src.models.openhours import OpenHours +from src.models.classes import ClassInstance, Class class Gym(Base): @@ -27,6 +28,7 @@ class Gym(Base): amenities = relationship("Amenity") facilities = relationship("Facility") hours = relationship("OpenHours") + classes = relationship("ClassInstance", back_populates="gym") image_url = Column(String, nullable=True) latitude = Column(Float, nullable=False) longitude = Column(Float, nullable=False) diff --git a/src/schema.py b/src/schema.py index fe63f09..ac72e77 100644 --- a/src/schema.py +++ b/src/schema.py @@ -6,6 +6,8 @@ from src.models.openhours import OpenHours as OpenHoursModel from src.models.amenity import Amenity as AmenityModel from src.models.equipment import Equipment as EquipmentModel +from src.models.classes import Class as ClassModel +from src.models.classes import ClassInstance as ClassInstanceModel # MARK: - Gym @@ -92,6 +94,16 @@ class Capacity(SQLAlchemyObjectType): class Meta: model = CapacityModel +# MARK: - Class +class Class(SQLAlchemyObjectType): + class Meta: + model = ClassModel + + +class ClassInstance(SQLAlchemyObjectType): + class Meta: + model = ClassInstanceModel + # MARK: - Activity # class Activity(SQLAlchemyObjectType): # class Meta: diff --git a/src/scrapers/class_scraper.py b/src/scrapers/class_scraper.py new file mode 100644 index 0000000..3a8c856 --- /dev/null +++ b/src/scrapers/class_scraper.py @@ -0,0 +1,190 @@ +from datetime import datetime +from src.database import db_session +import time as t +import datetime as dt +import random +from bs4 import BeautifulSoup +import re +import requests +# from src.constants import ( +# ASSET_BASE_URL, +# GYMS_BY_ID, +# ) +from src.utils.utils import get_gym_id +from src.utils.constants import GYMS +from src.models.classes import Class, ClassInstance +from src.models.openhours import OpenHours, RestrictionEnum, Restrictions, openhours_restrictions +from src.models.facility import Facility + + +BASE_URL = "https://scl.cornell.edu/recreation/" +CLASSES_PATH = "/fitness-centers/group-fitness-classes?&page=" +SPECIAL_HOURS_PATH = "/hours-facilities/cornell-fitness-center-special-hours" +POOL_HOURS_PATH = "/hours-facilities/pool-hours" + + +def create_group_class(class_href): + page = requests.get(BASE_URL + class_href).text + soup = BeautifulSoup(page, "lxml") + container = soup.select_one("#main-article") + name = container.select_one("h1").text + try: + contents = container.select("p") + except AttributeError as e: + print(e) + contents = [""] + description = "" + for c in contents: + if isinstance(c, str): + description += c + else: + description += c.text + model = Class(name=name, description=description) + db_session.add(model) + db_session.commit() + return model + + +""" +Scrape classes from the group-fitness-classes page +Params: + num_pages: number of pages to scrape +Returns: + dict of ClassInstance objects +""" +def scrape_classes(num_pages): + classes = {} + db_session.query(ClassInstance).delete() + db_session.commit() + for i in range(num_pages): + page = requests.get(BASE_URL + CLASSES_PATH + str(i)).text + soup = BeautifulSoup(page, "lxml") + if len(soup.find_all("table")) == 1: + continue + schedule = soup.find_all("table")[1] # first table is irrelevant + data = schedule.find_all("tr")[1:] # first row is header + for row in data: + row_elems = row.find_all("td") + class_instance = ClassInstance() + class_name = row_elems[0].a.text + class_href = row_elems[0].a["href"] + try: + gym_class = db_session.query(Class).filter(Class.name == class_name).first() + assert gym_class is not None + except AssertionError: + gym_class = create_group_class(class_href) + class_instance.class_id = gym_class.id + date_string = row_elems[1].text.strip() + if "Today" in date_string: + date_string = datetime.strftime(datetime.now(), "%m/%d/%Y") + # special handling for time (cancelled) + + time_str = row_elems[3].string.replace("\n", "").strip() + if time_str != "" and time_str != 'Canceled': + class_instance.is_canceled = False + time_strs = time_str.split(" - ") + start_time_string = time_strs[0].strip() + end_time_string = time_strs[1].strip() + + class_instance.start_time = datetime.strptime(f"{date_string} {start_time_string}", "%m/%d/%Y %I:%M%p") + class_instance.end_time = datetime.strptime(f"{date_string} {end_time_string}", "%m/%d/%Y %I:%M%p") + else: + class_instance.isCanceled = True + + try: + class_instance.instructor = row_elems[4].a.string + except: + class_instance.instructor = "" + try: + location = row_elems[5].a.string + class_instance.location = location + for gym in GYMS: + if gym in location: + if gym == "Virtual": + class_instance.isVirtual = True + else: + gym_id = get_gym_id(gym) + class_instance.gym_id = gym_id + break + except: + gym_class.location = "" + # gym_class.id = generate_id(gym_class.details_id + date_string + gym_class.instructor) + # gym_class.image_url = get_image_url(class_details[class_href].name) + db_session.add(class_instance) + db_session.commit() + classes[class_instance.id] = class_instance + return classes + + +# def scrape_pool_hours(): +# db_session.query(openhours_restrictions).delete() +# db_session.query(OpenHours).delete() +# page = requests.get(BASE_URL + POOL_HOURS_PATH).text +# soup = BeautifulSoup(page, "lxml") +# schedules = soup.find_all("table") +# pool_hours = {} +# for table in schedules: +# rows = table.find_all("tr") +# if len(rows) <= 1: +# continue +# for schedule in rows[1:]: +# pool_name = schedule.find_all("td")[0].text.strip() +# times = [] +# for td in schedule.find_all( +# lambda tag: tag.name == "td" and (len(tag.findChildren()) > 0 or len(tag.text) > 0) +# )[1:]: +# day = re.findall( +# "(?:Women Only\s*)?(?:\d{1,2}:\d{2}(?:am|pm)) - (?:\d{1,2}:\d{2}(?:am|pm))(?:\s*\(shallow\))?|Closed", +# td.text, +# ) +# non_empty_hours = [] +# for interval in day: +# if interval: +# non_empty_hours.append(interval) +# times.append(non_empty_hours) +# if pool_name.count("Helen Newman Hall") > 0: +# pool_name = "Helen Newman Pool" +# if pool_name.count("Teagle") > 0: +# pool_name = "Teagle Pool" +# if pool_name not in pool_hours: +# pool_hours[pool_name] = [[], [], [], [], [], [], []] +# pool = db_session.query(Facility).filter_by(name=pool_name).first() +# for i in range(len(times)): +# day = times[i] +# for time in day: +# time_text = time.strip() +# try: +# if "Closed" in time_text: +# openhour = OpenHours(**{"facility_id": pool.id, "day": i, "end_time": dt.time(0), "start_time": dt.time(0), "restrictions": []}) +# closed_obj = db_session.query(Restrictions).filter_by(restriction='closed').first() +# openhour.restrictions.append(closed_obj) +# db_session.add(openhour) +# db_session.commit() +# pool_hours[pool_name][i].append(openhour) +# else: +# women_only = False +# shallow = False +# if "Women Only" in time: +# women_only = True +# time = time.replace("Women Only", "").strip() +# if "(shallow)" in time: +# shallow = True +# time = time.replace("(shallow)", "").strip() +# start_time_string, end_time_string = time.split(" - ") +# start_time = datetime.strptime(start_time_string, "%I:%M%p").time() +# end_time = datetime.strptime(end_time_string, "%I:%M%p").time() +# openhour = OpenHours( +# **{"facility_id": pool.id, "day": i, "end_time": end_time, "start_time": start_time, "restrictions": []} +# ) +# if women_only: +# women_only_obj = db_session.query(Restrictions).filter_by(restriction='women_only').first() +# openhour.restrictions.append(women_only_obj) +# if shallow: +# shallow_obj = db_session.query(Restrictions).filter_by(restriction='shallow_pool_only').first() +# openhour.restrictions.append(shallow_obj) +# db_session.add(openhour) +# db_session.commit() +# pool_hours[pool_name][i].append(openhour) +# except: +# pass +# return pool_hours \ No newline at end of file diff --git a/src/utils/constants.py b/src/utils/constants.py index a3166ea..e2c30b6 100644 --- a/src/utils/constants.py +++ b/src/utils/constants.py @@ -36,6 +36,9 @@ # Eastern Timezone EASTERN_TIMEZONE = "America/New_York" +# The list of gyms +GYMS = ["Helen Newman", "Toni Morrison", "Noyes", "Teagle"] + # The path for general gym hours GYM_HOUR_BASE_URL = "https://scl.cornell.edu/recreation/cornell-fitness-centers" From 0300589da3bd956328fdf9ddd50dab2903f7f0ef Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Fri, 1 Mar 2024 15:14:04 -0500 Subject: [PATCH 36/39] fixed scheduling of classes scraper and cleaned up code --- app.py | 11 +++- src/scrapers/class_scraper.py | 108 +++++----------------------------- src/utils/constants.py | 6 ++ 3 files changed, 31 insertions(+), 94 deletions(-) diff --git a/app.py b/app.py index 3033203..54f6c76 100644 --- a/app.py +++ b/app.py @@ -11,7 +11,7 @@ from src.scrapers.scraper_helpers import clean_past_hours from src.scrapers.sp_hours_scraper import fetch_sp_facility from src.scrapers.equipment_scraper import scrape_equipment -from src.scrapers.class_scraper import scrape_classes +from src.scrapers.class_scraper import fetch_classes from src.utils.utils import create_gym_table @@ -59,14 +59,21 @@ def scrape_capacities(): fetch_capacities() +# Scrape classes every hour +@scheduler.task("interval", id="scrape_classes", seconds=3600) +def scrape_classes(): + logging.info("Scraping classes from group-fitness-classes...") + + fetch_classes(3) + # Create database and fill it with data init_db() create_gym_table() +scrape_classes() scrape_hours() scrape_capacities() scrape_equipment() -scrape_classes() # Create schema.graphql with open("schema.graphql", "w+") as schema_file: diff --git a/src/scrapers/class_scraper.py b/src/scrapers/class_scraper.py index 3a8c856..6406bb7 100644 --- a/src/scrapers/class_scraper.py +++ b/src/scrapers/class_scraper.py @@ -6,23 +6,20 @@ from bs4 import BeautifulSoup import re import requests -# from src.constants import ( -# ASSET_BASE_URL, -# GYMS_BY_ID, -# ) from src.utils.utils import get_gym_id -from src.utils.constants import GYMS +from src.utils.constants import GYMS, BASE_URL, CLASSES_PATH from src.models.classes import Class, ClassInstance -from src.models.openhours import OpenHours, RestrictionEnum, Restrictions, openhours_restrictions -from src.models.facility import Facility - - -BASE_URL = "https://scl.cornell.edu/recreation/" -CLASSES_PATH = "/fitness-centers/group-fitness-classes?&page=" -SPECIAL_HOURS_PATH = "/hours-facilities/cornell-fitness-center-special-hours" -POOL_HOURS_PATH = "/hours-facilities/pool-hours" +from src.models.openhours import OpenHours +from src.models.facility import Facility +""" +Create a group class from a class page +Params: + class_href: href of class page from group-fitness-classes page +Returns: + Class Object created +""" def create_group_class(class_href): page = requests.get(BASE_URL + class_href).text soup = BeautifulSoup(page, "lxml") @@ -48,11 +45,11 @@ def create_group_class(class_href): """ Scrape classes from the group-fitness-classes page Params: - num_pages: number of pages to scrape + num_pages: number of pages to scrape - this determines how far in advance we scrape classes Returns: dict of ClassInstance objects """ -def scrape_classes(num_pages): +def fetch_classes(num_pages): classes = {} db_session.query(ClassInstance).delete() db_session.commit() @@ -77,6 +74,7 @@ def scrape_classes(num_pages): date_string = row_elems[1].text.strip() if "Today" in date_string: date_string = datetime.strftime(datetime.now(), "%m/%d/%Y") + # special handling for time (cancelled) time_str = row_elems[3].string.replace("\n", "").strip() @@ -88,6 +86,8 @@ def scrape_classes(num_pages): class_instance.start_time = datetime.strptime(f"{date_string} {start_time_string}", "%m/%d/%Y %I:%M%p") class_instance.end_time = datetime.strptime(f"{date_string} {end_time_string}", "%m/%d/%Y %I:%M%p") + if class_instance.end_time < datetime.now(): + continue else: class_instance.isCanceled = True @@ -108,83 +108,7 @@ def scrape_classes(num_pages): break except: gym_class.location = "" - # gym_class.id = generate_id(gym_class.details_id + date_string + gym_class.instructor) - # gym_class.image_url = get_image_url(class_details[class_href].name) db_session.add(class_instance) db_session.commit() classes[class_instance.id] = class_instance - return classes - - -# def scrape_pool_hours(): -# db_session.query(openhours_restrictions).delete() -# db_session.query(OpenHours).delete() -# page = requests.get(BASE_URL + POOL_HOURS_PATH).text -# soup = BeautifulSoup(page, "lxml") -# schedules = soup.find_all("table") -# pool_hours = {} -# for table in schedules: -# rows = table.find_all("tr") -# if len(rows) <= 1: -# continue -# for schedule in rows[1:]: -# pool_name = schedule.find_all("td")[0].text.strip() -# times = [] -# for td in schedule.find_all( -# lambda tag: tag.name == "td" and (len(tag.findChildren()) > 0 or len(tag.text) > 0) -# )[1:]: -# day = re.findall( -# "(?:Women Only\s*)?(?:\d{1,2}:\d{2}(?:am|pm)) - (?:\d{1,2}:\d{2}(?:am|pm))(?:\s*\(shallow\))?|Closed", -# td.text, -# ) -# non_empty_hours = [] -# for interval in day: -# if interval: -# non_empty_hours.append(interval) -# times.append(non_empty_hours) -# if pool_name.count("Helen Newman Hall") > 0: -# pool_name = "Helen Newman Pool" -# if pool_name.count("Teagle") > 0: -# pool_name = "Teagle Pool" -# if pool_name not in pool_hours: -# pool_hours[pool_name] = [[], [], [], [], [], [], []] -# pool = db_session.query(Facility).filter_by(name=pool_name).first() -# for i in range(len(times)): -# day = times[i] -# for time in day: -# time_text = time.strip() -# try: -# if "Closed" in time_text: -# openhour = OpenHours(**{"facility_id": pool.id, "day": i, "end_time": dt.time(0), "start_time": dt.time(0), "restrictions": []}) -# closed_obj = db_session.query(Restrictions).filter_by(restriction='closed').first() -# openhour.restrictions.append(closed_obj) -# db_session.add(openhour) -# db_session.commit() -# pool_hours[pool_name][i].append(openhour) -# else: -# women_only = False -# shallow = False -# if "Women Only" in time: -# women_only = True -# time = time.replace("Women Only", "").strip() -# if "(shallow)" in time: -# shallow = True -# time = time.replace("(shallow)", "").strip() -# start_time_string, end_time_string = time.split(" - ") -# start_time = datetime.strptime(start_time_string, "%I:%M%p").time() -# end_time = datetime.strptime(end_time_string, "%I:%M%p").time() -# openhour = OpenHours( -# **{"facility_id": pool.id, "day": i, "end_time": end_time, "start_time": start_time, "restrictions": []} -# ) -# if women_only: -# women_only_obj = db_session.query(Restrictions).filter_by(restriction='women_only').first() -# openhour.restrictions.append(women_only_obj) -# if shallow: -# shallow_obj = db_session.query(Restrictions).filter_by(restriction='shallow_pool_only').first() -# openhour.restrictions.append(shallow_obj) -# db_session.add(openhour) -# db_session.commit() -# pool_hours[pool_name][i].append(openhour) -# except: -# pass -# return pool_hours \ No newline at end of file + return classes \ No newline at end of file diff --git a/src/utils/constants.py b/src/utils/constants.py index e2c30b6..783d6ca 100644 --- a/src/utils/constants.py +++ b/src/utils/constants.py @@ -3,6 +3,9 @@ # URL for Uplift image assets ASSET_BASE_URL = "https://raw.githubusercontent.com/cuappdev/assets/master/uplift/" +# Base URL for Cornell Recreation Website +BASE_URL = "https://scl.cornell.edu/recreation/" + # The path for capacities C2C_URL = "https://connect2concepts.com/connect2/?type=bar&key=355de24d-d0e4-4262-ae97-bc0c78b92839&loc_status=false" @@ -30,6 +33,9 @@ # The marker for last updated in the HTML CAPACITY_MARKER_UPDATED = "Updated: " +# The path for group classes +CLASSES_PATH = "/fitness-centers/group-fitness-classes?&page=" + # Days of the week used in the spreadsheet DAYS_OF_WEEK = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] From ff81d1827fa17abf7f03d322bf3f88fbe38d3651 Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Mon, 8 Apr 2024 18:01:10 -0400 Subject: [PATCH 37/39] modified schema --- schema.graphql | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/schema.graphql b/schema.graphql index fad30f3..5a0f6eb 100644 --- a/schema.graphql +++ b/schema.graphql @@ -27,31 +27,29 @@ type Capacity { updated: Int! } -type Class { - id: ID! - name: String! - description: String! - gyms: [ClassInstance] +enum CourtType { + BASKETBALL + VOLLEYBALL + BADMINTON } -type ClassInstance { +type Equipment { id: ID! - gymId: Int - classId: Int! - location: String! - instructor: String! - isCanceled: Boolean! - isVirtual: Boolean! - startTime: DateTime - endTime: DateTime - class_: Class - gym: Gym + name: String! + equipmentType: EquipmentType! + facilityId: Int! + quantity: Int + accessibility: AccessibilityType } -enum CourtType { - BASKETBALL - VOLLEYBALL - BADMINTON +enum EquipmentType { + CARDIO + RACKS_AND_BENCHES + SELECTORIZED + MULTI_CABLE + FREE_WEIGHTS + MISCELLANEOUS + PLATE_LOADED } type Facility { @@ -81,7 +79,6 @@ type Gym { amenities: [Amenity] facilities: [Facility] hours: [OpenHours] - classes: [ClassInstance] } type OpenHours { From 4e3facb10fbe61c83e24f4e69367e8712f7eacbd Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Wed, 17 Apr 2024 17:25:21 -0400 Subject: [PATCH 38/39] testing login --- app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.py b/app.py index 54f6c76..c4b807d 100644 --- a/app.py +++ b/app.py @@ -1,5 +1,5 @@ import logging -from flask import Flask, render_template +from flask import Flask, render_template, redirect, url_for from flask_apscheduler import APScheduler from flask_graphql import GraphQLView from graphene import Schema From bb101e52c255f5c5667e830fd9a2005dc8ba9557 Mon Sep 17 00:00:00 2001 From: Isabella Hoie Date: Wed, 17 Apr 2024 18:14:37 -0400 Subject: [PATCH 39/39] added classes to schema --- schema.graphql | 24 ++++++++++++++++++++++++ src/models/classes.py | 4 ++-- src/schema.py | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/schema.graphql b/schema.graphql index 075191f..91103fa 100644 --- a/schema.graphql +++ b/schema.graphql @@ -38,6 +38,27 @@ type Capacity { updated: Int! } +type Class { + id: ID! + name: String! + description: String! + classInstances: [ClassInstance] +} + +type ClassInstance { + id: ID! + gymId: Int + classId: Int! + location: String! + instructor: String! + isCanceled: Boolean! + isVirtual: Boolean! + startTime: DateTime + endTime: DateTime + class_: Class + gym: Gym +} + enum CourtType { BASKETBALL VOLLEYBALL @@ -52,6 +73,8 @@ type CreateUser { user: User } +scalar DateTime + type EnterGiveaway { giveawayInstance: GiveawayInstance } @@ -117,6 +140,7 @@ type Gym { amenities: [Amenity] facilities: [Facility] hours: [OpenHours] + classes: [ClassInstance] } type Mutation { diff --git a/src/models/classes.py b/src/models/classes.py index f425509..4a563b1 100644 --- a/src/models/classes.py +++ b/src/models/classes.py @@ -33,7 +33,7 @@ class Class(Base): id = Column(Integer, primary_key=True) name = Column(String(), nullable=False) description = Column(String(), nullable=False) - gyms = relationship("ClassInstance", back_populates="class_") + class_instances = relationship("ClassInstance", back_populates="class_") def __init__(self, **kwargs): self.id = kwargs.get("id") @@ -60,7 +60,7 @@ class ClassInstance(Base): isVirtual = Column(Boolean(), nullable=False, default=False) start_time = Column(DateTime(), nullable=True) end_time = Column(DateTime(), nullable=True) - class_ = relationship("Class", back_populates="gyms") + class_ = relationship("Class", back_populates="class_instances") gym = relationship("Gym", back_populates="classes") def __init__(self, **kwargs): diff --git a/src/schema.py b/src/schema.py index 63efb19..54a1a06 100644 --- a/src/schema.py +++ b/src/schema.py @@ -119,6 +119,39 @@ class Price(SQLAlchemyObjectType): class Meta: model = PriceModel +# MARK: - Class + + +class Class(SQLAlchemyObjectType): + class Meta: + model = ClassModel + + class_instances = graphene.List(lambda: ClassInstance) + + def resolve_class_instances(self, info): + query = ClassInstance.get_query(info=info).filter(ClassInstanceModel.class_id == self.id) + return query + + + +# MARK: - Class Instance + + +class ClassInstance(SQLAlchemyObjectType): + class Meta: + model = ClassInstanceModel + + gym = graphene.Field(lambda: Gym) + class_ = graphene.Field(lambda: Class) + + def resolve_gym(self, info): + query = Gym.get_query(info=info).filter(GymModel.id == self.gym_id).first() + return query + + def resolve_class_(self, info): + query = Class.get_query(info=info).filter(ClassModel.id == self.class_id).first() + return query + # MARK: - Activity