diff --git a/db_init.py b/db_init.py index 798e285e..6be7eecb 100644 --- a/db_init.py +++ b/db_init.py @@ -49,7 +49,10 @@ ) for row_tuple in rpi_schools_rows: - row = RPISchools(name=row_tuple[0], description=row_tuple[1]) + row = RPISchools() + row.name = row_tuple[0] + row.description = row_tuple[1] + db.session.add(row) db.session.commit() @@ -78,21 +81,24 @@ ) for row_tuple in rpi_departments_rows: - row = RPIDepartments( - name=row_tuple[0], - description=row_tuple[1], - school_id=row_tuple[2], - id=row_tuple[3], - image="https://cdn-icons-png.flaticon.com/512/5310/5310672.png", - website="https://www.rpi.edu", - ) + row = RPIDepartments() + row.name = row_tuple[0] + row.description = row_tuple[1] + row.school_id = row_tuple[2] + row.id = row_tuple[3] + row.image = "https://cdn-icons-png.flaticon.com/512/5310/5310672.png" + row.website = "https://www.rpi.edu" + db.session.add(row) db.session.commit() class_years_rows = (2025, 2026, 2027, 2028, 2029, 2030, 2031) for row_item in class_years_rows: - row = ClassYears(class_year=row_item, active=True) + row = ClassYears() + row.class_year = row_item + row.active = True + db.session.add(row) db.session.commit() @@ -132,42 +138,43 @@ "https://rafaelcenzano.com", ) - lab_manager = LabManager(department_id=raf_test_user[5]) + lab_manager = LabManager() + lab_manager.department_id = raf_test_user[5] db.session.add(lab_manager) db.session.commit() - user = User( - id=raf_test_user[0], - email=raf_test_user[0] + "@rpi.edu", - first_name=raf_test_user[1], - last_name=raf_test_user[2], - preferred_name=raf_test_user[3], - class_year=raf_test_user[4], - lab_manager_id=lab_manager.id, - description=raf_test_user[6], - profile_picture=raf_test_user[7], - website=raf_test_user[8], - ) + user = User() + user.id = raf_test_user[0] + user.email = raf_test_user[0] + "@rpi.edu" + user.first_name = raf_test_user[1] + user.last_name = raf_test_user[2] + user.preferred_name = raf_test_user[3] + user.class_year = raf_test_user[4] + user.lab_manager_id = lab_manager.id + user.description = raf_test_user[6] + user.profile_picture = raf_test_user[7] + user.website = raf_test_user[8] db.session.add(user) db.session.commit() for row_tuple in lab_manager_rows: - lab_manager = LabManager(department_id=row_tuple[3]) + lab_manager = LabManager() + lab_manager.department_id = row_tuple[3] db.session.add(lab_manager) db.session.commit() - user = User( - id=row_tuple[0], - email=row_tuple[0] + "@rpi.edu", - first_name=row_tuple[1], - last_name=row_tuple[2], - lab_manager_id=lab_manager.id, - description=row_tuple[4], - profile_picture="https://www.svgrepo.com/show/206842/professor.svg", - ) + user = User() + user.id = row_tuple[0] + user.email = row_tuple[0] + "@rpi.edu" + user.first_name = row_tuple[1] + user.last_name = row_tuple[2] + user.lab_manager_id = lab_manager.id + user.description = row_tuple[4] + user.profile_picture = "https://www.svgrepo.com/show/206842/professor.svg" + db.session.add(user) db.session.commit() @@ -255,22 +262,22 @@ ) for row_tuple in opportunities_rows: - row = Opportunities( - name=row_tuple[0], - description=row_tuple[1], - recommended_experience=row_tuple[2], - pay=row_tuple[3], - one_credit=row_tuple[4], - two_credits=row_tuple[5], - three_credits=row_tuple[6], - four_credits=row_tuple[7], - semester=row_tuple[8], - year=row_tuple[9], - application_due=row_tuple[10], - active=row_tuple[11], - last_updated=row_tuple[12], - location=row_tuple[13], - ) + row = Opportunities() + row.name = row_tuple[0] + row.description = row_tuple[1] + row.recommended_experience = row_tuple[2] + row.pay = row_tuple[3] + row.one_credit = row_tuple[4] + row.two_credits = row_tuple[5] + row.three_credits = row_tuple[6] + row.four_credits = row_tuple[7] + row.semester = row_tuple[8] + row.year = row_tuple[9] + row.application_due = row_tuple[10] + row.active = row_tuple[11] + row.last_updated = row_tuple[12] + row.location = row_tuple[13] + db.session.add(row) db.session.commit() @@ -282,7 +289,10 @@ ) for row_tuple in courses_rows: - row = Courses(code=row_tuple[0], name=row_tuple[1]) + row = Courses() + row.code = row_tuple[0] + row.name = row_tuple[1] + db.session.add(row) db.session.commit() @@ -296,7 +306,10 @@ ) for row_tuple in majors_rows: - row = Majors(code=row_tuple[0], name=row_tuple[1]) + row = Majors() + row.code = row_tuple[0] + row.name = row_tuple[1] + db.session.add(row) db.session.commit() @@ -313,28 +326,40 @@ ) for r in leads_rows: - row = Leads(lab_manager_id=r[0], opportunity_id=r[1]) + row = Leads() + row.lab_manager_id = r[0] + row.opportunity_id = r[1] + db.session.add(row) db.session.commit() recommends_courses_rows = ((1, "CSCI4430"), (1, "CSCI2961"), (2, "CSCI4390")) for r in recommends_courses_rows: - row = RecommendsCourses(opportunity_id=r[0], course_code=r[1]) + row = RecommendsCourses() + row.opportunity_id = r[0] + row.course_code = r[1] + db.session.add(row) db.session.commit() recommends_majors_rows = ((1, "CSCI"), (1, "PHYS"), (2, "BIOL")) for r in recommends_majors_rows: - row = RecommendsMajors(opportunity_id=r[0], major_code=r[1]) + row = RecommendsMajors() + row.opportunity_id = r[0] + row.major_code = r[1] + db.session.add(row) db.session.commit() recommends_class_years_rows = ((3, 2025), (2, 2025), (2, 2026), (1, 2027)) for r in recommends_class_years_rows: - row = RecommendsClassYears(opportunity_id=r[0], class_year=r[1]) + row = RecommendsClassYears() + row.opportunity_id = r[0] + row.class_year = r[1] + db.session.add(row) db.session.commit() @@ -345,10 +370,19 @@ ) for r in user_majors: - major = UserMajors(user_id=r[0], major_code=r[1]) - department = UserDepartments(user_id=r[0], department_id=r[1]) - db.session.add(major) - db.session.add(department) + row = UserMajors() + row.user_id = r[0] + row.major_code = r[1] + + db.session.add(row) + db.session.commit() + + for r in user_majors: + row = UserDepartments() + row.user_id = r[0] + row.department_id = r[1] + + db.session.add(row) db.session.commit() user_courses = ( @@ -358,7 +392,11 @@ ) for r in user_courses: - row = UserCourses(user_id=r[0], course_code=r[1], in_progress=r[2]) + row = UserCourses() + row.user_id = r[0] + row.course_code = r[1] + row.in_progress = r[2] + db.session.add(row) db.session.commit() @@ -370,7 +408,10 @@ ) for r in participates_rows: - row = Participates(user_id=r[0], opportunity_id=r[1]) + row = Participates() + row.user_id = r[0] + row.opportunity_id = r[1] + db.session.add(row) db.session.commit() diff --git a/docs/database_docs/Labconnect_DB.png b/docs/database_docs/Labconnect_DB.png index b8c8c39c..bcd496e7 100644 Binary files a/docs/database_docs/Labconnect_DB.png and b/docs/database_docs/Labconnect_DB.png differ diff --git a/labconnect/main/auth_routes.py b/labconnect/main/auth_routes.py index c822ac30..a251d6c5 100644 --- a/labconnect/main/auth_routes.py +++ b/labconnect/main/auth_routes.py @@ -35,11 +35,11 @@ def generate_temporary_code(user_email: str, registered: bool) -> str: def validate_code_and_get_user_email(code: str) -> tuple[str | None, bool | None]: token_data = temp_codes.get(code, {}) if not token_data: - return None + return None, None user_email = token_data.get("email", None) expire = token_data.get("expires_at", None) - registered = token_data.get("registered", None) + registered = token_data.get("registered", False) if user_email and expire and expire > datetime.now(): # If found, delete the code to prevent reuse @@ -108,49 +108,51 @@ def registerUser(): if not json_data: abort(400) - user = User( - email=json_data.get("email"), - first_name=json_data.get("first_name"), - last_name=json_data.get("last_name"), - preferred_name=json_data.get("preferred_name", ""), - class_year=json_data.get("class_year", ""), - profile_picture=json_data.get( - "profile_picture", "https://www.svgrepo.com/show/206842/professor.svg" - ), - website=json_data.get("website", ""), - description=json_data.get("description", ""), + user = User() + user.email = json_data.get("email") + user.first_name = json_data.get("first_name") + user.last_name = json_data.get("last_name") + user.preferred_name = json_data.get("preferred_name", "") + user.class_year = json_data.get("class_year", "") + user.profile_picture = json_data.get( + "profile_picture", "https://www.svgrepo.com/show/206842/professor.svg" ) + user.website = json_data.get("website", "") + user.description = json_data.get("description", "") db.session.add(user) db.session.commit() # Add UserDepartments if provided if json_data.get("departments"): for department_id in json_data["departments"]: - user_department = UserDepartments( - user_id=user.id, department_id=department_id - ) + user_department = UserDepartments() + user_department.department_id = department_id + user_department.user_id = user.id db.session.add(user_department) # Additional auxiliary records (majors, courses, etc.) if json_data.get("majors"): - for major_id in json_data["majors"]: - user_major = UserMajors(user_id=user.id, major_id=major_id) + for major_code in json_data["majors"]: + user_major = UserMajors() + user_major.user_id = user.id + user_major.major_code = major_code db.session.add(user_major) # Add Courses if provided if json_data.get("courses"): - for course_id in json_data["courses"]: - user_course = UserCourses(user_id=user.id, course_id=course_id) + for course_code in json_data["courses"]: + user_course = UserCourses() + user_course.user_id = user.id + user_course.course_code = course_code db.session.add(user_course) # Add ManagementPermissions if provided if json_data.get("permissions"): permissions = json_data["permissions"] - management_permissions = ManagementPermissions( - user_id=user.id, - super_admin=permissions.get("super_admin", False), - admin=permissions.get("admin", False), - moderator=permissions.get("moderator", False), - ) + management_permissions = ManagementPermissions() + management_permissions.user_id = user.id + management_permissions.super_admin = permissions.get("super_admin", False) + management_permissions.admin = permissions.get("admin", False) + management_permissions.moderator = permissions.get("moderator", False) db.session.add(management_permissions) db.session.commit() @@ -194,8 +196,5 @@ def metadataRoute(): @main_blueprint.get("/logout") def logout(): - if not current_app.config["TESTING"]: - # TODO: add token to blacklist - # current_app.config["TOKEN_BLACKLIST"].add() - pass + # TODO: add token to blacklist return {"msg": "logout successful"} diff --git a/labconnect/main/opportunity_routes.py b/labconnect/main/opportunity_routes.py index 52f95937..c2158bd0 100644 --- a/labconnect/main/opportunity_routes.py +++ b/labconnect/main/opportunity_routes.py @@ -13,6 +13,7 @@ RecommendsClassYears, User, Courses, + Participates, RecommendsMajors, ) @@ -496,7 +497,7 @@ def getOpportunityCards(): @main_blueprint.get("/staff/opportunities/") -def getLabManagerOpportunityCards(rcs_id: str): +def getLabManagerOpportunityCards(rcs_id: str) -> list[dict[str, str]]: query = ( db.select( @@ -518,61 +519,54 @@ def getLabManagerOpportunityCards(rcs_id: str): data = db.session.execute(query).all() - cards = { - "data": [ - { - "id": row[0], - "title": row[1], - "due": row[2].strftime("%-m/%-d/%y"), - "pay": row[3], - "credits": format_credits(row[4], row[5], row[6], row[7]), - } - for row in data - ] - } + cards = [ + { + "id": row[0], + "title": row[1], + "due": row[2].strftime("%-m/%-d/%y"), + "pay": row[3], + "credits": format_credits(row[4], row[5], row[6], row[7]), + } + for row in data + ] return cards -# @main_blueprint.get("/getProfileOpportunities/") -# def getProfileOpportunities(rcs_id: str): -# # # query database for opportunity - -# query = db.session.execute( -# db.select(Opportunities, Leads) -# .where(Leads.lab_manager_id == rcs_id) -# .join(Opportunities, Leads.opportunity_id == Opportunities.id) -# ) - -# data = query.all() - -# cards = {"data": []} +@main_blueprint.get("/profile/opportunities/") +def getProfileOpportunities(rcs_id: str) -> list[dict[str, str]]: -# for row in data: -# opportunity = row[0] - -# oppData = { -# "id": opportunity.id, -# "title": opportunity.name, -# "body": "Due " + str(opportunity.application_due), -# "attributes": [], -# "activeStatus": opportunity.active, -# } + query = ( + db.select( + Opportunities.id, + Opportunities.name, + Opportunities.application_due, + Opportunities.pay, + Opportunities.one_credit, + Opportunities.two_credits, + Opportunities.three_credits, + Opportunities.four_credits, + ) + .join(Participates, Participates.user_id == rcs_id) + .join(Opportunities, Participates.opportunity_id == Opportunities.id) + .where(User.id == rcs_id) + .select_from(User) + ) -# if opportunity.pay is not None and opportunity.pay > 0: -# oppData["attributes"].append("Paid") -# if ( -# opportunity.one_credit -# or opportunity.two_credits -# or opportunity.three_credits -# or opportunity.four_credits -# ): -# oppData["attributes"].append("Credits") + data = db.session.execute(query).all() -# cards["data"].append(oppData) + cards = [ + { + "id": row[0], + "title": row[1], + "due": row[2].strftime("%-m/%-d/%y"), + "pay": row[3], + "credits": format_credits(row[4], row[5], row[6], row[7]), + } + for row in data + ] -# # return data in the below format if opportunity is found -# return cards + return cards # function to search for lab managers diff --git a/labconnect/main/routes.py b/labconnect/main/routes.py index 0b5aa7ab..7c68809b 100644 --- a/labconnect/main/routes.py +++ b/labconnect/main/routes.py @@ -6,11 +6,12 @@ from labconnect import db from labconnect.models import ( LabManager, - Leads, Opportunities, RPIDepartments, User, ClassYears, + UserDepartments, + Majors, ) from . import main_blueprint @@ -88,95 +89,49 @@ def departmentDetails(department: str): return result -# @main_blueprint.get("/getSchoolsAndDepartments/") -# def getSchoolsAndDepartments(): -# data = db.session.execute( -# db.select(RPISchools, RPIDepartments).join( -# RPIDepartments, RPISchools.name == RPIDepartments.school_id -# ) -# ).scalars() - -# dictionary = {} -# for item in data: -# if item[0].name not in dictionary: -# dictionary[item[0].name] = [] -# dictionary[item[0].name].append(item[1].name) - -# return dictionary - - -# @main_blueprint.get("/getOpportunitiesRaw/") -# def getOpportunitiesRaw(id: int): -# data = db.session.execute( -# db.select( -# Opportunities, -# Leads, -# LabManager, -# RecommendsMajors, -# RecommendsCourses, -# RecommendsClassYears, -# ) -# .where(Opportunities.id == id) -# .join(Leads, Leads.opportunity_id == Opportunities.id) -# .join(LabManager, Leads.lab_manager_id == LabManager.id) -# .join(RecommendsMajors, RecommendsMajors.opportunity_id == Opportunities.id) -# .join(RecommendsCourses, RecommendsCourses.opportunity_id == Opportunities.id) -# .join( -# RecommendsClassYears, -# RecommendsClassYears.opportunity_id == Opportunities.id, -# ) -# ).scalars() - -# opportunities = [opportunity.to_dict() for opportunity in data] - -# return {"data": opportunities} - - -# @main_blueprint.get("/lab_manager") -# def getLabManagers(): -# if not request.data: -# abort(400) - -# json_request_data = request.get_json() - -# if not json_request_data: -# abort(400) - -# rcs_id = json_request_data.get("rcs_id", None) - -# if not rcs_id: -# abort(400) - -# data = db.first_or_404(db.select(LabManager).where(LabManager.id == rcs_id)) - -# result = data.to_dict() - -# return result - - @main_blueprint.get("/profile") +@jwt_required() def profile(): - request_data = request.get_json() - id = request_data.get("id", None) - # TODO: Fix to a join query - lab_manager = db.first_or_404(db.select(LabManager).where(LabManager.id == id)) - user = db.first_or_404(db.select(User).where(User.lab_manager_id == id)) - - result = lab_manager.to_dict() | user.to_dict() + user_id = get_jwt_identity() data = db.session.execute( - db.select(Opportunities, Leads) - .where(Leads.lab_manager_id == lab_manager.id) - .join(Opportunities, Leads.opportunity_id == Opportunities.id) - ).scalars() + db.select( + User.preferred_name, + User.first_name, + User.last_name, + User.profile_picture, + RPIDepartments.name, + User.description, + User.website, + User.lab_manager_id, + User.id, + ) + .where(User.email == user_id[0]) + .join(UserDepartments, UserDepartments.user_id == User.id) + .join(RPIDepartments, UserDepartments.department_id == RPIDepartments.id) + ).first() + + if not data: + return {"error": "profile not found"}, 404 + + # if data[7]: + # return {"lab_manager": True, "id": data[7]} - result["opportunities"] = [opportunity.to_dict() for opportunity in data] + result = { + "id": data[8], + "name": data[0] + " " + data[2] if data[0] else data[1] + " " + data[2], + "image": data[3], + "department": data[4], + "description": data[5], + "website": data[6], + } return result @main_blueprint.get("/staff/") +@jwt_required() def getProfessorProfile(id: str): data = db.session.execute( @@ -208,68 +163,6 @@ def getProfessorProfile(id: str): return result -# @main_blueprint.get("/lab_manager/opportunities") -# def getLabManagerOpportunityCards() -> dict[Any, list[Any]]: -# if not request.data: -# abort(400) - -# rcs_id = request.get_json().get("rcs_id", None) - -# if not rcs_id: -# abort(400) - -# data = db.session.execute( -# db.select(Opportunities, LabManager) -# .where(LabManager.id == rcs_id) -# .join(Leads, LabManager.id == Leads.lab_manager_id) -# .join(Opportunities, Leads.opportunity_id == Opportunities.id) -# .order_by(Opportunities.id) -# ).scalars() - -# if not data: -# abort(404) - -# result = {rcs_id: [opportunity.to_dict() for opportunity in data]} - -# return result - - -# _______________________________________________________________________________________________# - - -# Editing Opportunities in Profile Page -# @main_blueprint.get("/getProfessorCookies/") -# def getProfessorCookies(id: str): - -# # this is already restricted to "GET" requests - -# # TODO: Use JOIN query -# lab_manager = db.first_or_404(db.select(LabManager).where(LabManager.id == id)) -# user = db.first_or_404(db.select(User).where(User.lab_manager_id == id)) - -# dictionary = lab_manager.to_dict() | user.to_dict() - -# dictionary["role"] = "admin" -# dictionary["researchCenter"] = "AI" -# dictionary["loggedIn"] = True - -# return dictionary - - -# @main_blueprint.get("/getStaff/") -# def getStaff(department: str): -# query = db.session.execute( -# db.select(LabManager).filter(LabManager.department_id == department) -# ) -# data = query.all() -# dictionary = {} -# for item in data: -# dictionary[item[0].rcs_id] = item[0].to_dict() -# dictionary[item[0].rcs_id].pop("rcs_id") - -# return dictionary - - @main_blueprint.post("/changeActiveStatus") def changeActiveStatus() -> dict[str, bool]: data = request.get_json() @@ -313,42 +206,20 @@ def force_error(): # return result -# @main_blueprint.get("/majors") -# def majors() -> list[Any]: - -# if request.data: - -# json_request_data = request.get_json() - -# if not json_request_data: -# abort(400) +@main_blueprint.get("/majors") +def majors() -> list[dict[str, str]]: -# partial_key = json_request_data.get("input", None) + data = db.session.execute(db.select(Majors).order_by(Majors.code)).scalars() -# data = db.session.execute( -# db.select(Majors) -# .order_by(Majors.code) -# .where( -# (Majors.code.ilike(f"%{partial_key}%")) -# | (Majors.name.ilike(f"%{partial_key}%")) -# ) -# ).scalars() - -# if not data: -# abort(404) - -# result = [major.to_dict() for major in data] - -# return result - -# data = db.session.execute(db.select(Majors).order_by(Majors.code)).scalars() + if not data: + abort(404) -# if not data: -# abort(404) + result = [{"code": major.code, "name": major.name} for major in data] -# result = [major.to_dict() for major in data] + if result == []: + abort(404) -# return result + return result @main_blueprint.get("/years")