diff --git a/labconnect/main/opportunity_routes.py b/labconnect/main/opportunity_routes.py index 1dbfe145..775f26a8 100644 --- a/labconnect/main/opportunity_routes.py +++ b/labconnect/main/opportunity_routes.py @@ -766,6 +766,7 @@ def editOpportunity(opportunity_id): # db.session.commit() # Commit all changes + db.session.commit() return {"data": "Opportunity Updated"}, 200 @@ -810,6 +811,8 @@ def deleteOpportunity(opportunity_id): # Save User Opportunity + + @main_blueprint.post("/saveUserOpportunity/") @jwt_required() def saveUserOpportunity(opportunity_id): @@ -838,6 +841,7 @@ def saveUserOpportunity(opportunity_id): new_opp = UserSavedOpportunities() new_opp.user_id = save_opp_user_id new_opp.opportunity_id = save_opp_opportunity_id + db.session.add(new_opp) db.session.commit() @@ -873,3 +877,63 @@ def deleteUserOpportunity(opportunity_id): db.session.commit() return {"message": "Opportunity deleted"}, 200 + + +# Create route to return a list saved opportunities +@main_blueprint.get("/AllSavedUserOpportunities/") +@jwt_required() +def allSavedUserOportunities(): + # Get current users ID + user_id = get_jwt_identity() + + # Get all saved opportunities for the user + saved_opps = ( + db.session.execute( + db.select(UserSavedOpportunities).where( + UserSavedOpportunities.user_id == user_id + ) + ) + .scalars() + .all() + ) + if not saved_opps: + return {"message": "No saved opportunities found"}, 404 + + # Put opportunities into a dictionary + saved_opportunities_list = [opp.to_dict() for opp in saved_opps] + + return saved_opportunities_list, 200 + + +# Create route to allow for multiple pages to be unsaved given a list of opp_ids delete them +@main_blueprint.delete("/UnsaveMultiplePages/") +@jwt_required() +# Delete id that appear on delete_ids list +def UnsaveMultipleOpps(): + # Get a list of opportunity IDs + data = request.get_json() + delete_ids = data.get("delete_ids") + if not delete_ids or not isinstance(delete_ids, list): + return {"message": "Invalid or missing delete_ids"}, 400 + + # Get opportunities to delete for current user + user_id = get_jwt_identity() + saved_opps = ( + db.session.execute( + db.select(UserSavedOpportunities).where( + UserSavedOpportunities.user_id == user_id, + UserSavedOpportunities.opportunity_id.in_(delete_ids), + ) + ) + .scalars() + .all() + ) + if not saved_opps: + return {"message": "User has no saved opportunities"}, 404 + + # Delete the opportinities + for opp in saved_opps: + db.session.delete(opp) + + db.session.commit() + return {"message": f"Deleted {len(saved_opps)} saved opportunities"}, 200 diff --git a/migrations/env.py b/migrations/env.py index 4c970927..d004741b 100644 --- a/migrations/env.py +++ b/migrations/env.py @@ -12,32 +12,31 @@ # Interpret the config file for Python logging. # This line sets up loggers basically. fileConfig(config.config_file_name) -logger = logging.getLogger('alembic.env') +logger = logging.getLogger("alembic.env") def get_engine(): try: # this works with Flask-SQLAlchemy<3 and Alchemical - return current_app.extensions['migrate'].db.get_engine() + return current_app.extensions["migrate"].db.get_engine() except (TypeError, AttributeError): # this works with Flask-SQLAlchemy>=3 - return current_app.extensions['migrate'].db.engine + return current_app.extensions["migrate"].db.engine def get_engine_url(): try: - return get_engine().url.render_as_string(hide_password=False).replace( - '%', '%%') + return get_engine().url.render_as_string(hide_password=False).replace("%", "%%") except AttributeError: - return str(get_engine().url).replace('%', '%%') + return str(get_engine().url).replace("%", "%%") # add your model's MetaData object here # for 'autogenerate' support # from myapp import mymodel # target_metadata = mymodel.Base.metadata -config.set_main_option('sqlalchemy.url', get_engine_url()) -target_db = current_app.extensions['migrate'].db +config.set_main_option("sqlalchemy.url", get_engine_url()) +target_db = current_app.extensions["migrate"].db # other values from the config, defined by the needs of env.py, # can be acquired: @@ -46,7 +45,7 @@ def get_engine_url(): def get_metadata(): - if hasattr(target_db, 'metadatas'): + if hasattr(target_db, "metadatas"): return target_db.metadatas[None] return target_db.metadata @@ -64,9 +63,7 @@ def run_migrations_offline(): """ url = config.get_main_option("sqlalchemy.url") - context.configure( - url=url, target_metadata=get_metadata(), literal_binds=True - ) + context.configure(url=url, target_metadata=get_metadata(), literal_binds=True) with context.begin_transaction(): context.run_migrations() @@ -84,13 +81,13 @@ def run_migrations_online(): # when there are no changes to the schema # reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html def process_revision_directives(context, revision, directives): - if getattr(config.cmd_opts, 'autogenerate', False): + if getattr(config.cmd_opts, "autogenerate", False): script = directives[0] if script.upgrade_ops.is_empty(): directives[:] = [] - logger.info('No changes in schema detected.') + logger.info("No changes in schema detected.") - conf_args = current_app.extensions['migrate'].configure_args + conf_args = current_app.extensions["migrate"].configure_args if conf_args.get("process_revision_directives") is None: conf_args["process_revision_directives"] = process_revision_directives @@ -98,9 +95,7 @@ def process_revision_directives(context, revision, directives): with connectable.connect() as connection: context.configure( - connection=connection, - target_metadata=get_metadata(), - **conf_args + connection=connection, target_metadata=get_metadata(), **conf_args ) with context.begin_transaction():