Skip to content

Commit

Permalink
Merge pull request #80 from opportunity-hack/develop
Browse files Browse the repository at this point in the history
Volunteer Edit!
  • Loading branch information
gregv authored Aug 31, 2024
2 parents 3548821 + 002d19c commit f129983
Show file tree
Hide file tree
Showing 3 changed files with 205 additions and 5 deletions.
86 changes: 86 additions & 0 deletions api/messages/messages_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,92 @@ def update_npo(json):
"Updated NPO"
)

@limits(calls=50, period=ONE_MINUTE)
def update_hackathon_volunteers(event_id, json, propel_id):
db = get_db()
logger.info("Update Hackathon Volunteers")
logger.info("JSON: " + str(json))
send_slack_audit(action="update_hackathon_volunteers", message="Updating", payload=json)

# Since we know this user is an admin, prefix all vars with admin_
admin_email, admin_user_id, admin_last_login, admin_profile_image, admin_name, admin_nickname = get_propel_user_details_by_id(propel_id)

# Query for event_id column
doc = db.collection('hackathons').where("event_id", "==", event_id).stream()
doc = list(doc)
doc = doc[0] if len(doc) > 0 else None

# Convert from DocumentSnapshot to DocumentReference
if isinstance(doc, firestore.DocumentSnapshot):
doc = doc.reference

# If we don't find the event, return
if doc is None:
return Message("No Hackathon Found")

volunteer_type = json["type"]
timestamp = json["timestamp"]
name = json["name"]
# We will use timestamp and name to find the volunteer

if volunteer_type == "mentors":
logger.info("Updating Mentor")
# Get the mentor block
mentor_block = doc.get().to_dict()["mentors"]

# Find the mentor
for mentor in mentor_block:
logger.info(f"Comparing {mentor['name']} with {name} and {mentor['timestamp']} with {timestamp}")
if mentor["name"] == name and mentor["timestamp"] == timestamp:
# For each field in mentor, update with the new value from json
for key in mentor.keys():
if key in json:
if key == "timestamp" or key == "name": # Don't want to update these since they are primary keys
continue
mentor[key] = json[key]

mentor["updated_timestamp"] = datetime.now().isoformat()
mentor["updated_by"] = admin_name

logger.info(f"Found mentor {mentor}")
break
# Update the mentor block with the json for this mentor
doc.update({
"mentors": mentor_block
})
elif volunteer_type == "judge":
# Get the judge block
judge_block = doc.get().to_dict()["judges"]
# Find the judge
for judge in judge_block:
if judge["name"] == name and judge["timestamp"] == timestamp:
# For each field in judge, update with the new value from json
for key in judge.keys():
if key in json:
if key == "timestamp" or key == "name":
continue
judge[key] = json[key]
judge["updated_timestamp"] = datetime.now().isoformat()
judge["updated_by"] = admin_name

logger.info(f"Found judge {judge}")
break
# Update the judge block with the json for this judge
doc.update({
"judges": judge_block
})

# Clear cache
get_single_hackathon_event.cache_clear()

return Message(
"Updated Hackathon Volunteers"
)






@limits(calls=50, period=ONE_MINUTE)
def save_hackathon(json):
Expand Down
17 changes: 12 additions & 5 deletions api/messages/messages_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
get_single_hackathon_event,
get_single_hackathon_id,
save_hackathon,
update_hackathon_volunteers,
get_teams_list,
save_team,
unjoin_team,
Expand All @@ -47,6 +48,10 @@
bp_url_prefix = '/api/messages'
bp = Blueprint(bp_name, __name__, url_prefix=bp_url_prefix)

def getOrgId(req):
# Get the org_id from the req
return req.headers.get("X-Org-Id")


@bp.route("/public")
def public():
Expand Down Expand Up @@ -112,6 +117,13 @@ def submit_npo_application():
def add_hackathon():
return vars(save_hackathon(request.get_json()))

@bp.route("/hackathon/<event_id>/volunteers", methods=["PATCH"])
@auth.require_user
@auth.require_org_member_with_permission("volunteer.admin", req_to_org_id=getOrgId)
def update_hackathon_volunteers_mentors_judges(event_id):
if auth_user and auth_user.user_id:
return vars(update_hackathon_volunteers(event_id, request.get_json(), auth_user.user_id))


@bp.route("/hackathons", methods=["GET"])
def list_hackathons():
Expand Down Expand Up @@ -280,11 +292,6 @@ def get_profile_by_id(id):
return get_user_by_id_old(id)


def getOrgId(req):
# Get the org_id from the req
return req.headers.get("X-Org-Id")


# Used to provide profile details - user must be logged in
@bp.route("/admin/profiles", methods=["GET"])
@auth.require_org_member_with_permission("profile.admin", req_to_org_id=getOrgId)
Expand Down
107 changes: 107 additions & 0 deletions scripts/990_finder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import requests
import json
from datetime import datetime

def search_nonprofits(query, state, c_code, min_revenue=None, max_revenue=None, ntee=None):
base_url = "https://projects.propublica.org/nonprofits/api/v2/search.json"
params = {
"q": query,
"state[id]": state,
"c_code[id]": c_code
}

if ntee:
params["ntee[id]"] = ntee

response = requests.get(base_url, params=params)
if response.status_code == 200:
results = response.json()
filtered_results = []
for org in results.get('organizations', []):
if min_revenue is not None and org.get('income_amount', 0) < min_revenue:
continue
if max_revenue is not None and org.get('income_amount', 0) > max_revenue:
continue
filtered_results.append(org)
results['organizations'] = filtered_results
return results
else:
print(f"Error in search request: {response.status_code}")
return None

def get_organization_details(ein):
base_url = f"https://projects.propublica.org/nonprofits/api/v2/organizations/{ein}.json"

response = requests.get(base_url)
if response.status_code == 200:
return response.json()
else:
print(f"Error in organization details request: {response.status_code}")
return None

def print_organization_info(org):
print(f"Name: {org.get('name', 'N/A')}")
print(f"EIN: {org.get('ein', 'N/A')}")
print(f"STREIN: {org.get('strein', 'N/A')}")
print(f"City: {org.get('city', 'N/A')}")
print(f"State: {org.get('state', 'N/A')}")
print(f"NTEE Code: {org.get('ntee_code', 'N/A')}")
print(f"Subsection Code: {org.get('subseccd', 'N/A')}")
print(f"Classification Codes: {org.get('classification_codes', 'N/A')}")
print(f"Ruling Date: {org.get('ruling_date', 'N/A')}")
print(f"Income Amount: ${org.get('income_amount', 'N/A')}")
print("---")

def print_filing_info(filing):
print(f"Tax Period: {filing.get('tax_prd', 'N/A')}")
print(f"Total Revenue: ${filing.get('totrevenue', 'N/A')}")
print(f"Total Expenses: ${filing.get('totfuncexpns', 'N/A')}")
print(f"Total Assets: ${filing.get('totassetsend', 'N/A')}")
print(f"Total Liabilities: ${filing.get('totliabend', 'N/A')}")
print(f"Form Type: {['990', '990-EZ', '990-PF'][filing.get('formtype', 0)] if filing.get('formtype') is not None else 'N/A'}")
if filing.get('pdf_url'):
print(f"PDF URL: {filing['pdf_url']}")
print(f"Last Updated: {filing.get('updated', 'N/A')}")
print("---")

def main():
# Example usage with filters
query = "music"
state = "AZ"
c_code = "3"
min_revenue = 1000 # $1 million minimum revenue
max_revenue = None # 1000000 # $10 million maximum revenue
ntee = None # Education NTEE category

search_results = search_nonprofits(query, state, c_code, min_revenue, max_revenue, ntee)

if search_results:
print(f"Search Results (filtered by revenue ${min_revenue:,} - ${max_revenue} and NTEE category '{ntee}'):")
for org in search_results.get('organizations', [])[:5]: # Print first 5 results
print_organization_info(org)

# Get details for the first organization in the search results
if search_results.get('organizations'):
first_org_ein = search_results['organizations'][0].get('ein')
if first_org_ein:
org_details = get_organization_details(first_org_ein)

if org_details:
print("\nDetailed Organization Information:")
org = org_details.get('organization', {})
print_organization_info(org)

print("\nAll Filings Information:")
filings_with_data = org_details.get('filings_with_data', [])
if filings_with_data:
for filing in filings_with_data:
print_filing_info(filing)
else:
print("No filing data available.")
else:
print("No EIN found for the first organization in search results.")
else:
print("No organizations found matching the specified criteria.")

if __name__ == "__main__":
main()

0 comments on commit f129983

Please sign in to comment.