Spaces:
Running
Running
import os | |
import time | |
from datetime import datetime | |
import folium | |
import pandas as pd | |
import streamlit as st | |
from huggingface_hub import HfApi | |
from streamlit_folium import st_folium | |
from src.text_content import ( | |
COLOR_MAPPING, | |
ICON_MAPPING, | |
REVIEW_TEXT, | |
) | |
from src.utils import add_latlng_col, init_map, parse_gg_sheet, is_request_in_list, marker_request | |
import os | |
os.environ['STREAMLIT_UI_HIDE_SIDEBAR_NAV'] = 'True' | |
os.environ['STREAMLIT_UI_HIDE_TOP_BAR'] = 'True' | |
TOKEN = os.environ.get("HF_TOKEN", None) | |
REQUESTS_URL = "https://docs.google.com/spreadsheets/d/1gYoBBiBo1L18IVakHkf3t1fOGvHWb23loadyFZUeHJs/edit#gid=966953708" | |
INTERVENTIONS_URL = "https://docs.google.com/spreadsheets/d/1eXOTqunOWWP8FRdENPs4cU9ulISm4XZWYJJNR1-SrwY/edit#gid=2089222765" | |
api = HfApi(TOKEN) | |
# Initialize Streamlit Config | |
st.set_page_config( | |
layout="wide", | |
initial_sidebar_state="collapsed", | |
page_icon="🤝", | |
page_title="Nt3awnou Map نتعاونو", | |
) | |
hide_menu_style = """ | |
<style> | |
#MainMenu {visibility: hidden;} | |
</style> | |
""" | |
st.markdown(hide_menu_style, unsafe_allow_html=True) | |
st.markdown( | |
""" | |
<style> | |
.block-container { | |
padding-top: 0rem; | |
padding-bottom: 0rem; | |
padding-left: 0rem; | |
padding-right: 0rem; | |
} | |
.awesome-marker i { | |
font-size: 11px; | |
margin-top: 8px; | |
} | |
</style> | |
""", | |
unsafe_allow_html=True, | |
) | |
def display_interventions(interventions_df): | |
"""Display NGO interventions on the map""" | |
for index, row in interventions_df.iterrows(): | |
village_status = row[interventions_df.columns[7]] | |
if pd.isna(village_status): | |
continue | |
if ( | |
row[interventions_df.columns[5]] | |
== "Intervention prévue dans le futur / Planned future intervention" | |
): | |
# future intervention | |
color_mk = "pink" | |
status = "Planned ⌛" | |
elif ( | |
row[interventions_df.columns[5]] | |
!= "Intervention prévue dans le futur / Planned future intervention" | |
and village_status | |
!= "Critique, Besoin d'aide en urgence / Critical, in urgent need of help" | |
): | |
# past intervention and village not in a critical condition | |
color_mk = "green" | |
status = "Done ✅" | |
else: | |
color_mk = "darkgreen" | |
status = "Partial ⚠️" | |
intervention_type = row[interventions_df.columns[6]].split("/")[0].strip() | |
org = row[interventions_df.columns[1]] | |
city = row[interventions_df.columns[9]] | |
date = row[interventions_df.columns[4]] | |
population = row[interventions_df.columns[11]] | |
intervention_info = f"<b>Intervention Status:</b> {status}<br><b>Village Status:</b> {village_status.split('/')[0]}<br><b>Org:</b> {org}<br><b>Intervention:</b> {intervention_type}<br><b>Population:</b> {population}<br><b>📅 Date:</b> {date}" | |
if row["latlng"] is None: | |
continue | |
fg.add_child(folium.Marker( | |
location=row["latlng"], | |
tooltip=city, | |
popup=folium.Popup(intervention_info, max_width=300), | |
icon=folium.Icon(color=color_mk), | |
)) | |
def show_requests(filtered_df): | |
"""Display victim requests on the map""" | |
for index, row in filtered_df.iterrows(): | |
request_type = row["ما هي احتياجاتك؟ (أضفها إذا لم يتم ذكرها)"] | |
displayed_request = marker_request(request_type) | |
if pd.isna(request_type): | |
continue | |
long_lat = row[ | |
"هل يمكنك تقديم الإحداثيات الدقيقة للموقع؟ (ادا كنت لا توجد بعين المكان) متلاً \n31.01837503440344, -6.781405948842175" | |
] | |
maps_url = f"https://maps.google.com/?q={long_lat}" | |
# we display all requests in popup text and use the first one for the icon/color | |
display_text = f'<b>Request Type:</b> {request_type}<br><b>Id:</b> {row["id"]}<br><a href="{maps_url}" target="_blank" rel="noopener noreferrer"><b>Google Maps</b></a>' | |
icon_name = ICON_MAPPING.get(displayed_request, None) | |
if row["latlng"] is None: | |
continue | |
fg.add_child(folium.Marker( | |
location=row["latlng"], | |
tooltip=row[" لأي جماعة / قيادة / دوار تنتمون ؟"] | |
if not pd.isna(row[" لأي جماعة / قيادة / دوار تنتمون ؟"]) | |
else None, | |
popup=folium.Popup(display_text, max_width=300), | |
icon=folium.Icon( | |
color=COLOR_MAPPING.get(displayed_request, "blue"), icon=icon_name | |
), | |
)) | |
def display_google_sheet_tables(data_url): | |
"""Display the google sheet tables for requests and interventions""" | |
st.markdown( | |
f"""<iframe src="{data_url}" width="100%" height="600px"></iframe>""", | |
unsafe_allow_html=True, | |
) | |
def display_dataframe(df, drop_cols, data_url, search_id=True, status=False, for_help_requests=False): | |
"""Display the dataframe in a table""" | |
col_1, col_2 = st.columns([1, 1]) | |
with col_1: | |
query = st.text_input( | |
"🔍 Search for information / بحث عن المعلومات", | |
key=f"search_requests_{int(search_id)}", | |
) | |
with col_2: | |
if search_id: | |
id_number = st.number_input( | |
"🔍 Search for an id / بحث عن رقم", | |
min_value=0, | |
max_value=len(filtered_df), | |
value=0, | |
step=1, | |
) | |
if status: | |
selected_status = st.selectbox( | |
"🗓️ Status / حالة", | |
["all / الكل", "Done / تم", "Planned / مخطط لها"], | |
key="status", | |
) | |
if query: | |
# Filtering the dataframe based on the query | |
mask = df.apply(lambda row: row.astype(str).str.contains(query).any(), axis=1) | |
display_df = df[mask] | |
else: | |
display_df = df | |
display_df = display_df.drop(drop_cols, axis=1) | |
if search_id and id_number: | |
display_df = display_df[display_df["id"] == id_number] | |
if status: | |
target = "Pouvez-vous nous préciser si vous êtes déjà intervenus ou si vous prévoyez de le faire | Tell us if you already made the intervention, or if you're planning to do it" | |
if selected_status == "Done / تم": | |
display_df = display_df[ | |
display_df[target] == "Intervention déjà passée / Past intevention" | |
] | |
elif selected_status == "Planned / مخطط لها": | |
display_df = display_df[ | |
display_df[target] != "Intervention déjà passée / Past intevention" | |
] | |
st.dataframe(display_df, height=500) | |
st.markdown( | |
f"To view the full Google Sheet for advanced filtering go to: {data_url} **لعرض الورقة كاملة، اذهب إلى**" | |
) | |
# if we want to check hidden contact information | |
if for_help_requests: | |
st.markdown( | |
"We are hiding contact information to protect the privacy of the victims. If you are an NGO and want to contact the victims, please contact us at [email protected]", | |
) | |
st.markdown( | |
""" | |
<div style="text-align: left;"> | |
<a href="mailto:[email protected]">[email protected]</a> نحن نخفي معلومات الاتصال لحماية خصوصية الضحايا. إذا كنت جمعية وتريد الاتصال بالضحايا، يرجى الاتصال بنا على | |
</div> | |
""", | |
unsafe_allow_html=True, | |
) | |
def id_review_submission(): | |
"""Id review submission form""" | |
st.subheader("🔍 Review of requests") | |
st.markdown(REVIEW_TEXT) | |
id_to_review = st.number_input( | |
"Enter id / أدخل الرقم", min_value=0, max_value=len(df), value=0, step=1 | |
) | |
reason_for_review = st.text_area("Explain why / أدخل سبب المراجعة") | |
if st.button("Submit / أرسل"): | |
if reason_for_review == "": | |
st.error("Please enter a reason / الرجاء إدخال سبب") | |
else: | |
filename = f"review_id_{id_to_review}_{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.txt" | |
with open(filename, "w") as f: | |
f.write(f"id: {id_to_review}, explanation: {reason_for_review}\n") | |
api.upload_file( | |
path_or_fileobj=filename, | |
path_in_repo=filename, | |
repo_id="nt3awnou/review_requests", | |
repo_type="dataset", | |
) | |
st.success( | |
"Submitted at https://huggingface.co/datasets/nt3awnou/review_requests/ تم الإرسال" | |
) | |
# # Logo and Title | |
# st.markdown(LOGO, unsafe_allow_html=True) | |
# # st.title("Nt3awnou نتعاونو") | |
# st.markdown(SLOGAN, unsafe_allow_html=True) | |
# Load data and initialize map with plugins | |
df = parse_gg_sheet(REQUESTS_URL) | |
df = add_latlng_col(df, process_column=15) | |
interventions_df = parse_gg_sheet(INTERVENTIONS_URL) | |
interventions_df = add_latlng_col(interventions_df, process_column=12) | |
m = init_map() | |
fg = folium.FeatureGroup(name="Markers") | |
# Selection of requests | |
options = [ | |
"إغاثة", | |
"مساعدة طبية", | |
"مأوى", | |
"طعام وماء", | |
"مخاطر (تسرب الغاز، تلف في الخدمات العامة...)", | |
] | |
selected_options = [] | |
# st.markdown( | |
# "👉 **Choose request type | Choissisez le type de demande | اختر نوع الطلب**" | |
# ) | |
# col1, col2, col3, col4, col5 = st.columns([2, 3, 2, 3, 4]) | |
# cols = [col1, col2, col3, col4, col5] | |
# for i, option in enumerate(options): | |
# checked = cols[i].checkbox(HEADERS_MAPPING[option], value=True) | |
# if checked: | |
# selected_options.append(option) | |
df["id"] = df.index | |
# keep rows with at least one request in selected_options | |
filtered_df = df[df["ما هي احتياجاتك؟ (أضفها إذا لم يتم ذكرها)"].apply( | |
lambda x: is_request_in_list(x, selected_options) | |
)] | |
# # keep rows with at least one request in selected_options | |
# filtered_df = df[df["ما هي احتياجاتك؟ (أضفها إذا لم يتم ذكرها)"].apply( | |
# lambda x: is_request_in_list(x, selected_options) | |
# )] | |
display_interventions(interventions_df) | |
# # Show requests | |
show_requests(df) | |
st_folium(m, use_container_width=True, returned_objects=[], feature_group_to_add=fg, key="map") | |