From 0c81e5c3dcd289888163607e6c3b20a38b307b9e Mon Sep 17 00:00:00 2001 From: Greg V Date: Sun, 11 Aug 2024 08:30:16 -0700 Subject: [PATCH 1/3] added process link to email --- api/messages/messages_service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/messages/messages_service.py b/api/messages/messages_service.py index 48c4c5d..1637c1f 100644 --- a/api/messages/messages_service.py +++ b/api/messages/messages_service.py @@ -996,7 +996,6 @@ def send_nonprofit_welcome_email(organization_name, contact_name, email): TODO: Add these pages and then move these down into the email we send
  • Access Your Nonprofit Dashboard - Track your project's progress
  • -
  • Understanding Our Process - Learn how we match you with volunteers
  • Nonprofit Resources - Helpful guides for working with tech teams
  • Success Stories - See how other nonprofits have benefited
  • @@ -1024,6 +1023,7 @@ def send_nonprofit_welcome_email(organization_name, contact_name, email):

    What's Next?

    From 08297555ccd46be6cbf7bc978cc1abfc44c25911 Mon Sep 17 00:00:00 2001 From: Greg V Date: Sun, 11 Aug 2024 14:54:34 -0700 Subject: [PATCH 2/3] Added success stories to nonprofit application welcome email --- api/messages/messages_service.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/api/messages/messages_service.py b/api/messages/messages_service.py index 1637c1f..80a47fc 100644 --- a/api/messages/messages_service.py +++ b/api/messages/messages_service.py @@ -997,7 +997,6 @@ def send_nonprofit_welcome_email(organization_name, contact_name, email):
  • Access Your Nonprofit Dashboard - Track your project's progress
  • Nonprofit Resources - Helpful guides for working with tech teams
  • -
  • Success Stories - See how other nonprofits have benefited
  • Submit or Update Your Project
  • Tips for Communicating with Volunteers
  • @@ -1029,7 +1028,7 @@ def send_nonprofit_welcome_email(organization_name, contact_name, email):

    Important Links:

    From 71dfcf0432b760643ed78240ab409f56d3e5dd59 Mon Sep 17 00:00:00 2001 From: Greg V Date: Sat, 17 Aug 2024 22:17:28 -0700 Subject: [PATCH 3/3] volunteer tracking feature --- api/users/users_views.py | 32 ++++++++++++++- model/user.py | 4 +- services/users_service.py | 83 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 115 insertions(+), 4 deletions(-) diff --git a/api/users/users_views.py b/api/users/users_views.py index d3ae0b5..6f5ecbd 100644 --- a/api/users/users_views.py +++ b/api/users/users_views.py @@ -42,4 +42,34 @@ def get_profile_by_db_id(id): if p: return p #Already a dict else: - return None \ No newline at end of file + return None + + +@bp.route("/volunteering", methods=["POST"]) +@auth.require_user +def save_volunteering_time(): + if auth_user and auth_user.user_id: + u: User | None = users_service.save_volunteering_time(auth_user.user_id, request.get_json()) + return vars(u) if u is not None else None + else: + return None + + +@bp.route("/volunteering", methods=["GET"]) +@auth.require_user +def get_volunteering_time(): + # Get url params + start_date = request.args.get('start_date') + end_date = request.args.get('end_date') + + if auth_user and auth_user.user_id: + volunteering, total = users_service.get_volunteering_time(auth_user.user_id, start_date, end_date) + return { + "totalHours": total, + "volunteering": volunteering + } + else: + return None + + + \ No newline at end of file diff --git a/model/user.py b/model/user.py index 3641ccd..a13e878 100644 --- a/model/user.py +++ b/model/user.py @@ -1,4 +1,4 @@ -metadata_list = ["role", "expertise", "education", "company", "why", "shirt_size", "github"] +metadata_list = ["role", "expertise", "education", "company", "why", "shirt_size", "github", "volunteering"] class User: id = None @@ -19,6 +19,7 @@ class User: teams = [] hackathons = [] history = {} + volunteering = [] @classmethod def deserialize(cls, d): @@ -37,6 +38,7 @@ def deserialize(cls, d): u.role = d['role'] if 'role' in d else '' u.company = d['company'] if 'company' in d else '' u.why = d['why'] if 'why' in d else '' + u.volunteering = d['volunteering'] if 'volunteering' in d else [] # Handle history in a generic way ''' diff --git a/services/users_service.py b/services/users_service.py index 1543b43..6f758a1 100644 --- a/services/users_service.py +++ b/services/users_service.py @@ -11,8 +11,8 @@ from cachetools.keys import hashkey from common.log import get_log_level -logger = logging.getLogger("ohack") -logger.setLevel(get_log_level()) +logger = logging.getLogger("myapp") +logger.setLevel(logging.INFO) #TODO consts file? ONE_MINUTE = 1*60 @@ -267,3 +267,82 @@ def remove_user_by_slack_id(user_id): @limits(calls=100, period=ONE_MINUTE) def get_users(): return fetch_users() + +def save_volunteering_time(propel_id, json): + logger.info(f"Save Volunteering Time for {propel_id} {json}") + slack_user = get_slack_user_from_propel_user_id(propel_id) + slack_user_id = slack_user["sub"] + + logger.info(f"Save Volunteering Time for {slack_user_id} {json}") + + # Get the user + user = fetch_user_by_user_id(slack_user_id) + if user is None: + logger.error(f"User not found for {slack_user_id}") + return + + timestamp = datetime.now().isoformat() + "Z" + reason = json["reason"] # The kind of volunteering being done + + if "finalHours" in json: + finalHours = json["finalHours"] # This is sent at when volunteering is done + if finalHours is None: + logger.error(f"finalHours is None for {slack_user_id}") + return + + user.volunteering.append({ + "timestamp": timestamp, + "finalHours": round(finalHours,2), + "reason": reason + }) + + # Add to the total + upsert_profile_metadata(user) + + # We keep track of what the user is committing to do but we don't show this + # The right way to do this is likely to get a session id when they start volunteering and the frontend uses that to close out the volunteering session when it is done + # But this way is simpler for now + elif "commitmentHours" in json: + commitmentHours = json["commitmentHours"] # This is sent at the start of volunteering + if commitmentHours is None: + logger.error(f"commitmentHours is None for {slack_user_id}") + return + + user.volunteering.append({ + "timestamp": timestamp, + "commitmentHours": round(commitmentHours,2), + "reason": reason + }) + upsert_profile_metadata(user) + + # Clear cache for get_profile_metadata + get_profile_metadata.cache_clear() + + return user + + +def get_volunteering_time(propel_id, start_date, end_date): + logger.info(f"Get Volunteering Time for {propel_id} {start_date} {end_date}") + slack_user = get_slack_user_from_propel_user_id(propel_id) + slack_user_id = slack_user["sub"] + + logger.info(f"Get Volunteering Time for {slack_user_id} start: {start_date} end: {end_date}") + + # Get the user + user = fetch_user_by_user_id(slack_user_id) + if user is None: + return + + # Filter the volunteering data + volunteering = [] + for v in user.volunteering: + if "finalHours" in v: + if start_date is not None and end_date is not None: + if v["timestamp"] >= start_date and v["timestamp"] <= end_date: + volunteering.append(v) + else: + volunteering.append(v) + + total = sum([v["finalHours"] for v in volunteering]) + + return volunteering, total \ No newline at end of file