Skip to content

Commit

Permalink
Merge pull request #79 from opportunity-hack/develop
Browse files Browse the repository at this point in the history
Time tracking
  • Loading branch information
gregv authored Aug 18, 2024
2 parents 381cd3f + 71dfcf0 commit 3548821
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 7 deletions.
5 changes: 2 additions & 3 deletions api/messages/messages_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -996,9 +996,7 @@ def send_nonprofit_welcome_email(organization_name, contact_name, email):
TODO: Add these pages and then move these down into the email we send
<li><a href="{add_utm('https://ohack.dev/nonprofits/dashboard', content=image_utm_content)}">Access Your Nonprofit Dashboard</a> - Track your project's progress</li>
<li><a href="{add_utm('https://ohack.dev/about/process', content=image_utm_content)}">Understanding Our Process</a> - Learn how we match you with volunteers</li>
<li><a href="{add_utm('https://ohack.dev/nonprofits/resources', content=image_utm_content)}">Nonprofit Resources</a> - Helpful guides for working with tech teams</li>
<li><a href="{add_utm('https://ohack.dev/nonprofits/success-stories', content=image_utm_content)}">Success Stories</a> - See how other nonprofits have benefited</li>
<li><a href="{add_utm('https://ohack.dev/nonprofits/project-submission', content=image_utm_content)}">Submit or Update Your Project</a></li>
<li><a href="{add_utm('https://ohack.dev/nonprofits/volunteer-communication', content=image_utm_content)}">Tips for Communicating with Volunteers</a></li>
Expand All @@ -1024,12 +1022,13 @@ def send_nonprofit_welcome_email(organization_name, contact_name, email):
<h2 style="color: #0088FE;">What's Next?</h2>
<ul>
<li><a href="{add_utm('https://ohack.dev/office-hours', content=image_utm_content)}">Join our weekly Office Hours</a> - Get your questions answered</li>
<li><a href="{add_utm('https://ohack.dev/about/process', content=image_utm_content)}">Understanding Our Process</a> - Learn how we match you with volunteers</li>
<li><a href="{add_utm('https://ohack.dev/nonprofits', content=image_utm_content)}">Explore Nonprofit Projects</a> - See what we've worked on</li>
</ul>
<h2 style="color: #0088FE;">Important Links:</h2>
<ul>
<li><a href="{add_utm('https://www.ohack.dev/about/success-stories', content=image_utm_content)}">Success Stories</a> - See how other nonprofits have benefited</li>
<li><a href="{add_utm('https://www.ohack.dev/hack', content=image_utm_content)}">Upcoming Hackathons and Events</a></li>
</ul>
Expand Down
32 changes: 31 additions & 1 deletion api/users/users_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,34 @@ def get_profile_by_db_id(id):
if p:
return p #Already a dict
else:
return None
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



4 changes: 3 additions & 1 deletion model/user.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -19,6 +19,7 @@ class User:
teams = []
hackathons = []
history = {}
volunteering = []

@classmethod
def deserialize(cls, d):
Expand All @@ -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
'''
Expand Down
83 changes: 81 additions & 2 deletions services/users_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

0 comments on commit 3548821

Please sign in to comment.