Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
Commit
•
9ff2d70
1
Parent(s):
5fe0186
quick fixes
Browse files- app.py +17 -54
- src/text_content.py +3 -3
- src/utils.py +44 -12
app.py
CHANGED
@@ -4,11 +4,10 @@ from datetime import datetime
|
|
4 |
|
5 |
import folium
|
6 |
import pandas as pd
|
7 |
-
import requests
|
8 |
import streamlit as st
|
9 |
-
from folium import plugins
|
10 |
from huggingface_hub import HfApi
|
11 |
from streamlit_folium import st_folium
|
|
|
12 |
|
13 |
from src.text_content import (
|
14 |
COLOR_MAPPING,
|
@@ -27,7 +26,9 @@ from src.utils import init_map, parse_gg_sheet
|
|
27 |
|
28 |
TOKEN = os.environ.get("HF_TOKEN", None)
|
29 |
REQUESTS_URL = "https://docs.google.com/spreadsheets/d/1gYoBBiBo1L18IVakHkf3t1fOGvHWb23loadyFZUeHJs/edit#gid=966953708"
|
30 |
-
INTERVENTIONS_URL =
|
|
|
|
|
31 |
api = HfApi(TOKEN)
|
32 |
|
33 |
|
@@ -40,52 +41,24 @@ if "sleep_time" not in st.session_state:
|
|
40 |
if "auto_refresh" not in st.session_state:
|
41 |
st.session_state.auto_refresh = False
|
42 |
|
43 |
-
# Session for Requests
|
44 |
-
session = requests.Session()
|
45 |
-
|
46 |
auto_refresh = st.sidebar.checkbox("Auto Refresh?", st.session_state.auto_refresh)
|
47 |
if auto_refresh:
|
48 |
-
number = st.sidebar.number_input(
|
49 |
-
"Refresh rate in seconds", value=st.session_state.sleep_time
|
50 |
-
)
|
51 |
st.session_state.sleep_time = number
|
52 |
|
53 |
|
54 |
-
# Utility functions
|
55 |
-
@st.cache_data(persist=True)
|
56 |
-
def parse_latlng_from_link(url):
|
57 |
-
try:
|
58 |
-
# extract latitude and longitude from gmaps link
|
59 |
-
if "@" not in url:
|
60 |
-
resp = session.head(url, allow_redirects=True)
|
61 |
-
url = resp.url
|
62 |
-
latlng = url.split("@")[1].split(",")[0:2]
|
63 |
-
return [float(latlng[0]), float(latlng[1])]
|
64 |
-
except Exception as e:
|
65 |
-
return None
|
66 |
-
|
67 |
-
|
68 |
-
def parse_gg_sheet_interventions(url):
|
69 |
-
url = url.replace("edit#gid=", "export?format=csv&gid=")
|
70 |
-
print(url)
|
71 |
-
df = pd.read_csv(url, on_bad_lines="skip")
|
72 |
-
return df.assign(latlng=df.iloc[:, 3].apply(parse_latlng_from_link))
|
73 |
-
|
74 |
-
|
75 |
# Streamlit functions
|
76 |
def display_interventions(interventions_df, m):
|
77 |
"""Display NGO interventions on the map"""
|
78 |
for index, row in interventions_df.iterrows():
|
79 |
status = (
|
80 |
"Done ✅"
|
81 |
-
if row[interventions_df.columns[5]]
|
82 |
-
!= "Intervention prévue dans le futur / Planned future intervention"
|
83 |
else "Planned ⌛"
|
84 |
)
|
85 |
color_mk = (
|
86 |
"green"
|
87 |
-
if row[interventions_df.columns[5]]
|
88 |
-
!= "Intervention prévue dans le futur / Planned future intervention"
|
89 |
else "pink"
|
90 |
)
|
91 |
intervention_type = row[interventions_df.columns[6]].split("/")[0].strip()
|
@@ -122,13 +95,10 @@ def show_requests(filtered_df, m):
|
|
122 |
if not pd.isna(row[" لأي جماعة / قيادة / دوار تنتمون ؟"])
|
123 |
else None,
|
124 |
popup=folium.Popup(display_text, max_width=300),
|
125 |
-
icon=folium.Icon(
|
126 |
-
color=COLOR_MAPPING.get(request_type, "blue"), icon=icon_name
|
127 |
-
),
|
128 |
).add_to(m)
|
129 |
|
130 |
|
131 |
-
|
132 |
def display_google_sheet_tables(data_url):
|
133 |
"""Display the google sheet tables for requests and interventions"""
|
134 |
st.markdown(
|
@@ -177,14 +147,10 @@ def display_dataframe(df, drop_cols, data_url, search_id=True, status=False):
|
|
177 |
if status:
|
178 |
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"
|
179 |
if selected_status == "Done / تم":
|
180 |
-
display_df = display_df[
|
181 |
-
display_df[target] == "Intervention déjà passée / Past intevention"
|
182 |
-
]
|
183 |
|
184 |
elif selected_status == "Planned / مخطط لها":
|
185 |
-
display_df = display_df[
|
186 |
-
display_df[target] != "Intervention déjà passée / Past intevention"
|
187 |
-
]
|
188 |
|
189 |
st.dataframe(display_df, height=500)
|
190 |
st.markdown(
|
@@ -198,9 +164,7 @@ def id_review_submission():
|
|
198 |
st.markdown(REVIEW_TEXT)
|
199 |
st.markdown(REVIEW_TEXT_2)
|
200 |
|
201 |
-
id_to_review = st.number_input(
|
202 |
-
"Enter id / أدخل الرقم", min_value=0, max_value=len(df), value=0, step=1
|
203 |
-
)
|
204 |
reason_for_review = st.text_area("Explain why / أدخل سبب المراجعة")
|
205 |
if st.button("Submit / أرسل"):
|
206 |
if reason_for_review == "":
|
@@ -215,14 +179,12 @@ def id_review_submission():
|
|
215 |
repo_id="nt3awnou/review_requests",
|
216 |
repo_type="dataset",
|
217 |
)
|
218 |
-
st.success(
|
219 |
-
"Submitted at https://huggingface.co/datasets/nt3awnou/review_requests/ تم الإرسال"
|
220 |
-
)
|
221 |
|
222 |
|
223 |
# Logo and Title
|
224 |
st.markdown(LOGO, unsafe_allow_html=True)
|
225 |
-
st.title("Nt3awnou نتعاونو
|
226 |
st.markdown(SLOGAN, unsafe_allow_html=True)
|
227 |
|
228 |
# Language tabs
|
@@ -235,11 +197,11 @@ with tab_ar:
|
|
235 |
st.markdown(INTRO_TEXT_AR, unsafe_allow_html=True)
|
236 |
with tab_fr:
|
237 |
st.markdown(INTRO_TEXT_FR, unsafe_allow_html=True)
|
238 |
-
|
239 |
-
|
240 |
# Load data and initialize map with plugins
|
241 |
df = parse_gg_sheet(REQUESTS_URL)
|
242 |
-
|
|
|
|
|
243 |
m = init_map()
|
244 |
|
245 |
# Selection of requests
|
@@ -278,6 +240,7 @@ show_interventions = st.checkbox(
|
|
278 |
)
|
279 |
|
280 |
if show_interventions:
|
|
|
281 |
display_interventions(interventions_df, m)
|
282 |
|
283 |
# Show requests
|
|
|
4 |
|
5 |
import folium
|
6 |
import pandas as pd
|
|
|
7 |
import streamlit as st
|
|
|
8 |
from huggingface_hub import HfApi
|
9 |
from streamlit_folium import st_folium
|
10 |
+
from src.utils import add_latlng_col
|
11 |
|
12 |
from src.text_content import (
|
13 |
COLOR_MAPPING,
|
|
|
26 |
|
27 |
TOKEN = os.environ.get("HF_TOKEN", None)
|
28 |
REQUESTS_URL = "https://docs.google.com/spreadsheets/d/1gYoBBiBo1L18IVakHkf3t1fOGvHWb23loadyFZUeHJs/edit#gid=966953708"
|
29 |
+
INTERVENTIONS_URL = (
|
30 |
+
"https://docs.google.com/spreadsheets/d/1eXOTqunOWWP8FRdENPs4cU9ulISm4XZWYJJNR1-SrwY/edit#gid=2089222765"
|
31 |
+
)
|
32 |
api = HfApi(TOKEN)
|
33 |
|
34 |
|
|
|
41 |
if "auto_refresh" not in st.session_state:
|
42 |
st.session_state.auto_refresh = False
|
43 |
|
|
|
|
|
|
|
44 |
auto_refresh = st.sidebar.checkbox("Auto Refresh?", st.session_state.auto_refresh)
|
45 |
if auto_refresh:
|
46 |
+
number = st.sidebar.number_input("Refresh rate in seconds", value=st.session_state.sleep_time)
|
|
|
|
|
47 |
st.session_state.sleep_time = number
|
48 |
|
49 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
# Streamlit functions
|
51 |
def display_interventions(interventions_df, m):
|
52 |
"""Display NGO interventions on the map"""
|
53 |
for index, row in interventions_df.iterrows():
|
54 |
status = (
|
55 |
"Done ✅"
|
56 |
+
if row[interventions_df.columns[5]] != "Intervention prévue dans le futur / Planned future intervention"
|
|
|
57 |
else "Planned ⌛"
|
58 |
)
|
59 |
color_mk = (
|
60 |
"green"
|
61 |
+
if row[interventions_df.columns[5]] != "Intervention prévue dans le futur / Planned future intervention"
|
|
|
62 |
else "pink"
|
63 |
)
|
64 |
intervention_type = row[interventions_df.columns[6]].split("/")[0].strip()
|
|
|
95 |
if not pd.isna(row[" لأي جماعة / قيادة / دوار تنتمون ؟"])
|
96 |
else None,
|
97 |
popup=folium.Popup(display_text, max_width=300),
|
98 |
+
icon=folium.Icon(color=COLOR_MAPPING.get(request_type, "blue"), icon=icon_name),
|
|
|
|
|
99 |
).add_to(m)
|
100 |
|
101 |
|
|
|
102 |
def display_google_sheet_tables(data_url):
|
103 |
"""Display the google sheet tables for requests and interventions"""
|
104 |
st.markdown(
|
|
|
147 |
if status:
|
148 |
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"
|
149 |
if selected_status == "Done / تم":
|
150 |
+
display_df = display_df[display_df[target] == "Intervention déjà passée / Past intevention"]
|
|
|
|
|
151 |
|
152 |
elif selected_status == "Planned / مخطط لها":
|
153 |
+
display_df = display_df[display_df[target] != "Intervention déjà passée / Past intevention"]
|
|
|
|
|
154 |
|
155 |
st.dataframe(display_df, height=500)
|
156 |
st.markdown(
|
|
|
164 |
st.markdown(REVIEW_TEXT)
|
165 |
st.markdown(REVIEW_TEXT_2)
|
166 |
|
167 |
+
id_to_review = st.number_input("Enter id / أدخل الرقم", min_value=0, max_value=len(df), value=0, step=1)
|
|
|
|
|
168 |
reason_for_review = st.text_area("Explain why / أدخل سبب المراجعة")
|
169 |
if st.button("Submit / أرسل"):
|
170 |
if reason_for_review == "":
|
|
|
179 |
repo_id="nt3awnou/review_requests",
|
180 |
repo_type="dataset",
|
181 |
)
|
182 |
+
st.success("Submitted at https://huggingface.co/datasets/nt3awnou/review_requests/ تم الإرسال")
|
|
|
|
|
183 |
|
184 |
|
185 |
# Logo and Title
|
186 |
st.markdown(LOGO, unsafe_allow_html=True)
|
187 |
+
st.title("Nt3awnou نتعاونو")
|
188 |
st.markdown(SLOGAN, unsafe_allow_html=True)
|
189 |
|
190 |
# Language tabs
|
|
|
197 |
st.markdown(INTRO_TEXT_AR, unsafe_allow_html=True)
|
198 |
with tab_fr:
|
199 |
st.markdown(INTRO_TEXT_FR, unsafe_allow_html=True)
|
|
|
|
|
200 |
# Load data and initialize map with plugins
|
201 |
df = parse_gg_sheet(REQUESTS_URL)
|
202 |
+
df = add_latlng_col(df, process_column=15)
|
203 |
+
interventions_df = parse_gg_sheet(INTERVENTIONS_URL)
|
204 |
+
interventions_df = add_latlng_col(interventions_df, process_column=11)
|
205 |
m = init_map()
|
206 |
|
207 |
# Selection of requests
|
|
|
240 |
)
|
241 |
|
242 |
if show_interventions:
|
243 |
+
# print(interventions_df.columns)
|
244 |
display_interventions(interventions_df, m)
|
245 |
|
246 |
# Show requests
|
src/text_content.py
CHANGED
@@ -25,9 +25,9 @@ INTRO_TEXT_FR = """
|
|
25 |
Nt3awnou نتعاونو est une plateforme collaborative dédiée à l'aide aux personnes touchées par le récent tremblement de terre au Maroc. Notre mission principale est de rationaliser et de coordonner une assistance rapide pour toutes les personnes touchées. Comment y parvenons-nous ? Nous aidons les personnes dans le besoin en leur permettant de communiquer leur localisation et l'aide spécifique dont elles ont besoin, soit en remplissant un formulaire, soit en envoyant un message vocal via WhatsApp à un numéro désigné. Une fois reçues et traitées, ces informations peuvent être consultées dans notre tableau de bord, qui permet aux associations d'organiser et de cibler précisément leurs interventions, afin que l'aide parvienne rapidement à ceux qui en ont besoin. Toute organisation ayant pris une initiative dans une zone particulière peut nous en informer en remplissant un formulaire prévu à cet effet. Ces données sont également intégrées au tableau de bord afin que d'autres associations puissent aider les zones touchées qui n'ont pas encore reçu d'aide.
|
26 |
Avertissement : Il y a encore des chutes de pierres dans les montagnes, ce qui rend les routes vers les zones touchées très dangereuses. Nous conseillons aux volontaires de faire des dons directement aux associations spécialisées.
|
27 |
|
28 |
-
Vous pouvez nous contacter par courrier électronique à l'adresse suivante : nt3awnou@annarabic.com
|
29 |
-
Aidez-nous à signaler plus de personnes dans le besoin en remplissant ce formulaire : https://forms.gle/nZNCUVog9ka2Vdqu6
|
30 |
-
Les associations peuvent signaler leurs interventions en remplissant ce formulaire : https://forms.gle/PsNSuHHjTTgwQMmVA
|
31 |
</div>
|
32 |
"""
|
33 |
|
|
|
25 |
Nt3awnou نتعاونو est une plateforme collaborative dédiée à l'aide aux personnes touchées par le récent tremblement de terre au Maroc. Notre mission principale est de rationaliser et de coordonner une assistance rapide pour toutes les personnes touchées. Comment y parvenons-nous ? Nous aidons les personnes dans le besoin en leur permettant de communiquer leur localisation et l'aide spécifique dont elles ont besoin, soit en remplissant un formulaire, soit en envoyant un message vocal via WhatsApp à un numéro désigné. Une fois reçues et traitées, ces informations peuvent être consultées dans notre tableau de bord, qui permet aux associations d'organiser et de cibler précisément leurs interventions, afin que l'aide parvienne rapidement à ceux qui en ont besoin. Toute organisation ayant pris une initiative dans une zone particulière peut nous en informer en remplissant un formulaire prévu à cet effet. Ces données sont également intégrées au tableau de bord afin que d'autres associations puissent aider les zones touchées qui n'ont pas encore reçu d'aide.
|
26 |
Avertissement : Il y a encore des chutes de pierres dans les montagnes, ce qui rend les routes vers les zones touchées très dangereuses. Nous conseillons aux volontaires de faire des dons directement aux associations spécialisées.
|
27 |
|
28 |
+
✉️ Vous pouvez nous contacter par courrier électronique à l'adresse suivante : nt3awnou@annarabic.com <br>
|
29 |
+
📝 Aidez-nous à signaler plus de personnes dans le besoin en remplissant ce formulaire : https://forms.gle/nZNCUVog9ka2Vdqu6 <br>
|
30 |
+
📝 Les associations peuvent signaler leurs interventions en remplissant ce formulaire : https://forms.gle/PsNSuHHjTTgwQMmVA
|
31 |
</div>
|
32 |
"""
|
33 |
|
src/utils.py
CHANGED
@@ -9,22 +9,54 @@ BORDER_COLOR = "black"
|
|
9 |
|
10 |
def parse_gg_sheet(url):
|
11 |
url = url.replace("edit#gid=", "export?format=csv&gid=")
|
12 |
-
print(url)
|
13 |
df = pd.read_csv(url, on_bad_lines="warn")
|
|
|
14 |
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
return df
|
27 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
def add_epicentre_to_map(map_obj):
|
30 |
icon_epicentre = folium.plugins.BeautifyIcon(
|
|
|
9 |
|
10 |
def parse_gg_sheet(url):
|
11 |
url = url.replace("edit#gid=", "export?format=csv&gid=")
|
|
|
12 |
df = pd.read_csv(url, on_bad_lines="warn")
|
13 |
+
return df
|
14 |
|
15 |
+
# Session for Requests
|
16 |
+
# session = requests.Session()
|
17 |
+
# @st.cache_data(persist=True)
|
18 |
+
# def parse_latlng_from_link(url):
|
19 |
+
# try:
|
20 |
+
# # extract latitude and longitude from gmaps link
|
21 |
+
# if "@" not in url:
|
22 |
+
# resp = session.head(url, allow_redirects=True)
|
23 |
+
# url = resp.url
|
24 |
+
# latlng = url.split("@")[1].split(",")[0:2]
|
25 |
+
# return [float(latlng[0]), float(latlng[1])]
|
26 |
+
# except Exception as e:
|
27 |
+
# return None
|
28 |
+
|
29 |
+
def add_latlng_col(df, process_column):
|
30 |
+
"""Add a latlng column to the dataframe"""
|
31 |
+
df = df.assign(latlng=df.iloc[:, process_column].apply(parse_latlng))
|
32 |
return df
|
33 |
|
34 |
+
# parse latlng (column 4) to [lat, lng]
|
35 |
+
import re
|
36 |
+
def parse_latlng(latlng):
|
37 |
+
if pd.isna(latlng):
|
38 |
+
return None
|
39 |
+
# lat, lng = latlng.split(",")
|
40 |
+
# return [float(lat), float(lng)]
|
41 |
+
|
42 |
+
try:
|
43 |
+
# check if it matches (30.9529832, -7.1010705) or (30.9529832,-7.1010705)
|
44 |
+
if re.match(r"\(\d+\.\d+,\s?-\d+\.\d+\)", latlng):
|
45 |
+
lat, lng = latlng[1:-1].split(",")
|
46 |
+
return [float(lat), float(lng)]
|
47 |
+
# check of it matches 30.9529832, -7.1010705 or 30.9529832,-7.1010705
|
48 |
+
elif re.match(r"\d+\.\d+,\s?-\d+\.\d+", latlng):
|
49 |
+
lat, lng = latlng.split(",")
|
50 |
+
return [float(lat), float(lng)]
|
51 |
+
# check if it matches 30,9529832, -7,1010705 or 30,9529832,-7,1010705, match1=30,9529832 and match2=-7,1010705
|
52 |
+
elif re.match(r"\d+,\d+,\s?-\d+,\d+", latlng):
|
53 |
+
d1, d2, d3, d4 = latlng.split(",")
|
54 |
+
return [float(".".join([d1, d2])), float(".".join([d3, d4]))]
|
55 |
+
except Exception as e:
|
56 |
+
print(f"Error parsing latlng: {latlng} Reason: {e}")
|
57 |
+
return None
|
58 |
+
print(f"Error parsing latlng: {latlng}")
|
59 |
+
return None
|
60 |
|
61 |
def add_epicentre_to_map(map_obj):
|
62 |
icon_epicentre = folium.plugins.BeautifyIcon(
|