feat: color theme change / error management / dead section
Browse files- app/assets/config/config_checkbox_physical.json +1 -1
- app/assets/config/config_dropdown_circumstances.json +2 -2
- app/circumstances/circumstances_dropdowns.py +7 -7
- app/dead.py +16 -3
- app/{gallery.py → display.py} +22 -16
- app/main_multianimal.py +106 -45
- app/styling/style.py +20 -2
- app/styling/theme.py +96 -10
- app/validation_submission/create_json.py +5 -1
- app/validation_submission/processing.py +0 -55
- app/validation_submission/submission.py +5 -4
- app/validation_submission/validation.py +113 -39
app/assets/config/config_checkbox_physical.json
CHANGED
@@ -11,7 +11,7 @@
|
|
11 |
"Description": "Obvious bone fracture"},
|
12 |
"Injury": {
|
13 |
"Description": "Visible skin injury"},
|
14 |
-
"
|
15 |
"Description": "Maggots, fleas, lice, louseflies"},
|
16 |
"Swelling": {
|
17 |
"Description": "Marked swelling without injury"},
|
|
|
11 |
"Description": "Obvious bone fracture"},
|
12 |
"Injury": {
|
13 |
"Description": "Visible skin injury"},
|
14 |
+
"Parasite": {
|
15 |
"Description": "Maggots, fleas, lice, louseflies"},
|
16 |
"Swelling": {
|
17 |
"Description": "Marked swelling without injury"},
|
app/assets/config/config_dropdown_circumstances.json
CHANGED
@@ -6,11 +6,11 @@
|
|
6 |
"Options": {
|
7 |
"road_type" : ["highway", "main road", "secondary road", "local road/path/trail", "parking lot", "other road", "unknown road"]
|
8 |
},
|
9 |
-
"Open": "
|
10 |
},
|
11 |
"train":
|
12 |
{
|
13 |
-
"Open": "
|
14 |
},
|
15 |
"aircraft": {},
|
16 |
"boat": {},
|
|
|
6 |
"Options": {
|
7 |
"road_type" : ["highway", "main road", "secondary road", "local road/path/trail", "parking lot", "other road", "unknown road"]
|
8 |
},
|
9 |
+
"Open": "Infrastructure_number"
|
10 |
},
|
11 |
"train":
|
12 |
{
|
13 |
+
"Open": "Infrastructure_number"
|
14 |
},
|
15 |
"aircraft": {},
|
16 |
"boat": {},
|
app/circumstances/circumstances_dropdowns.py
CHANGED
@@ -100,13 +100,13 @@ def on_select_dropdown_level2(evt: gr.SelectData):
|
|
100 |
"circumstance_option_dropdown",
|
101 |
evt.value.lower())
|
102 |
|
103 |
-
def on_change_openfield_level2(evt: gr.EventData):
|
104 |
-
print("Saving open field")
|
105 |
-
add_data_tmp("wounded_dead",
|
106 |
-
"circumstance_open_field",
|
107 |
-
evt.value.lower())
|
108 |
-
|
109 |
def on_select_dropdown_extra_level2(evt: gr.SelectData):
|
110 |
add_data_tmp("wounded_dead",
|
111 |
"circumstance_extra",
|
112 |
-
evt.value.lower())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
"circumstance_option_dropdown",
|
101 |
evt.value.lower())
|
102 |
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
def on_select_dropdown_extra_level2(evt: gr.SelectData):
|
104 |
add_data_tmp("wounded_dead",
|
105 |
"circumstance_extra",
|
106 |
+
evt.value.lower())
|
107 |
+
|
108 |
+
def on_change_openfield_level2(openfield_level2_dead):
|
109 |
+
print("Saving open field")
|
110 |
+
add_data_tmp("wounded_dead",
|
111 |
+
"circumstance_open_field",
|
112 |
+
str(openfield_level2_dead).lower())
|
app/dead.py
CHANGED
@@ -1,5 +1,7 @@
|
|
1 |
import gradio as gr
|
2 |
from circumstances.circumstances import create_circumstances
|
|
|
|
|
3 |
from follow_up.followup_events import create_followup_dropdowns, create_followup_open
|
4 |
from validation_submission.add_json import add_data_to_individual
|
5 |
|
@@ -10,10 +12,18 @@ def show_section_dead(visible):
|
|
10 |
|
11 |
with gr.Column(visible=visible, elem_id="dead") as section_dead:
|
12 |
gr.Markdown("# Dead Animal")
|
13 |
-
gr.Markdown("## Please describe the cause of death", label="description")
|
14 |
|
15 |
-
|
|
|
|
|
16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
gr.Markdown("## Follow-Up Events", label="Title")
|
18 |
gr.Markdown("Please tell us what you did with the animal.", label="description")
|
19 |
with gr.Row():
|
@@ -22,6 +32,9 @@ def show_section_dead(visible):
|
|
22 |
fe_name_recipient, fe_collection_ref = create_followup_open(visible, "dead")
|
23 |
|
24 |
|
25 |
-
return section_dead,
|
|
|
26 |
dropdown, dropdown_level2, openfield_level2, dropdown_extra_level2, \
|
|
|
|
|
27 |
fe_collection_dropdown, fe_recepient_dropdown, fe_radio_dropdown, fe_answer_dropdown, fe_name_recipient, fe_collection_ref
|
|
|
1 |
import gradio as gr
|
2 |
from circumstances.circumstances import create_circumstances
|
3 |
+
from physical.physical_select_animal import create_bird_anatomy
|
4 |
+
from physical.physical_checkbox import process_body_parts
|
5 |
from follow_up.followup_events import create_followup_dropdowns, create_followup_open
|
6 |
from validation_submission.add_json import add_data_to_individual
|
7 |
|
|
|
12 |
|
13 |
with gr.Column(visible=visible, elem_id="dead") as section_dead:
|
14 |
gr.Markdown("# Dead Animal")
|
|
|
15 |
|
16 |
+
gr.Markdown("## Do you know what conditions caused this?", label="description")
|
17 |
+
radio_cause = gr.Radio(["Yes", "No"], value=None, show_label=False, interactive=True)
|
18 |
+
button_collision, button_deliberate_destruction, button_indirect_destruction, button_natural_cause, dropdown, dropdown_level2, openfield_level2, dropdown_extra_level2 = create_circumstances(visible=False)
|
19 |
|
20 |
+
gr.Markdown("## Are there physical changes on the bird?" , label="description")
|
21 |
+
radio_physical = gr.Radio(["Yes", "No"], value=None, show_label=False, interactive=True)
|
22 |
+
with gr.Row():
|
23 |
+
physical_boxes = create_bird_anatomy(False, "dead")
|
24 |
+
with gr.Column():
|
25 |
+
checkbox_beak, text_beak, checkbox_body, text_body, checkbox_feathers, text_feathers, checkbox_head, text_head, checkbox_legs, text_legs = process_body_parts("dead", "None")
|
26 |
+
|
27 |
gr.Markdown("## Follow-Up Events", label="Title")
|
28 |
gr.Markdown("Please tell us what you did with the animal.", label="description")
|
29 |
with gr.Row():
|
|
|
32 |
fe_name_recipient, fe_collection_ref = create_followup_open(visible, "dead")
|
33 |
|
34 |
|
35 |
+
return section_dead, radio_cause, radio_physical,\
|
36 |
+
button_collision, button_deliberate_destruction, button_indirect_destruction, button_natural_cause, \
|
37 |
dropdown, dropdown_level2, openfield_level2, dropdown_extra_level2, \
|
38 |
+
physical_boxes, \
|
39 |
+
checkbox_beak, text_beak, checkbox_body, text_body, checkbox_feathers, text_feathers, checkbox_head, text_head, checkbox_legs, text_legs, \
|
40 |
fe_collection_dropdown, fe_recepient_dropdown, fe_radio_dropdown, fe_answer_dropdown, fe_name_recipient, fe_collection_ref
|
app/{gallery.py → display.py}
RENAMED
@@ -1,5 +1,9 @@
|
|
1 |
import gradio as gr
|
2 |
import pandas as pd
|
|
|
|
|
|
|
|
|
3 |
|
4 |
from validation_submission.submission import validate_save_individual
|
5 |
from validation_submission.get_json import get_json_all_individuals
|
@@ -7,9 +11,19 @@ from validation_submission.get_json import get_json_all_individuals
|
|
7 |
HEADERS = ["Identifier", "Location", "Wounded", "Dead"]
|
8 |
|
9 |
|
10 |
-
|
11 |
-
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
def convert_image(image_base64_str):
|
14 |
im = Image.open(BytesIO(base64.b64decode(image_base64_str)))
|
15 |
return im
|
@@ -23,15 +37,6 @@ def set_gallery_size(len_animals):
|
|
23 |
num_rows = len_animals/(num_cols)
|
24 |
return num_cols, num_rows
|
25 |
|
26 |
-
def save_individual_to_gallery(gallery, df):
|
27 |
-
validate_save_individual()
|
28 |
-
all_animals = get_json_all_individuals()
|
29 |
-
gallery_animals = process_animals_for_gallery(all_animals)
|
30 |
-
gallery = make_gallery(gallery_animals)
|
31 |
-
df_animals = process_animals_for_df(all_animals)
|
32 |
-
df = make_df(df_animals)
|
33 |
-
return gallery, df
|
34 |
-
|
35 |
def process_animals_for_gallery(all_animals):
|
36 |
gallery_animals = []
|
37 |
for _, animal in all_animals.items():
|
@@ -72,6 +77,8 @@ def keep_only_values(dict_to_filter):
|
|
72 |
info_text = "NaN"
|
73 |
return info_text
|
74 |
|
|
|
|
|
75 |
|
76 |
def process_animals_for_df(all_animals):
|
77 |
df_animals = {}
|
@@ -101,14 +108,13 @@ def process_animals_for_df(all_animals):
|
|
101 |
def make_df(df_animals):
|
102 |
df = pd.DataFrame.from_dict(df_animals)
|
103 |
styled_df = df.style.set_properties(**{
|
104 |
-
'
|
|
|
105 |
'white-space': 'normal', # Allows text to wrap to the next line
|
106 |
'word-wrap': 'break-word' # Breaks long words to fit within the width
|
107 |
})
|
108 |
df_gradio = gr.DataFrame(visible=True,
|
109 |
-
value=
|
110 |
headers=HEADERS, interactive=False)
|
111 |
-
# df = gr.DataFrame(visible=True,
|
112 |
-
# headers=HEADERS)
|
113 |
return df_gradio
|
114 |
|
|
|
1 |
import gradio as gr
|
2 |
import pandas as pd
|
3 |
+
from gradio_modal import Modal
|
4 |
+
from PIL import Image
|
5 |
+
from io import BytesIO
|
6 |
+
import base64
|
7 |
|
8 |
from validation_submission.submission import validate_save_individual
|
9 |
from validation_submission.get_json import get_json_all_individuals
|
|
|
11 |
HEADERS = ["Identifier", "Location", "Wounded", "Dead"]
|
12 |
|
13 |
|
14 |
+
def save_display_individual(gallery, df, error_box):
|
15 |
+
individual, error_box = validate_save_individual(error_box)
|
16 |
+
if individual:
|
17 |
+
all_animals = get_json_all_individuals()
|
18 |
+
gallery_animals = process_animals_for_gallery(all_animals)
|
19 |
+
gallery = make_gallery(gallery_animals)
|
20 |
+
df_animals = process_animals_for_df(all_animals)
|
21 |
+
df = make_df(df_animals)
|
22 |
+
return gallery, df, error_box
|
23 |
+
|
24 |
+
# ----------------------------------
|
25 |
+
# GALLERY
|
26 |
+
|
27 |
def convert_image(image_base64_str):
|
28 |
im = Image.open(BytesIO(base64.b64decode(image_base64_str)))
|
29 |
return im
|
|
|
37 |
num_rows = len_animals/(num_cols)
|
38 |
return num_cols, num_rows
|
39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
def process_animals_for_gallery(all_animals):
|
41 |
gallery_animals = []
|
42 |
for _, animal in all_animals.items():
|
|
|
77 |
info_text = "NaN"
|
78 |
return info_text
|
79 |
|
80 |
+
# ----------------------------------
|
81 |
+
# DATAFRAME
|
82 |
|
83 |
def process_animals_for_df(all_animals):
|
84 |
df_animals = {}
|
|
|
108 |
def make_df(df_animals):
|
109 |
df = pd.DataFrame.from_dict(df_animals)
|
110 |
styled_df = df.style.set_properties(**{
|
111 |
+
'min-width': '25px',
|
112 |
+
'max-width': '50px', # Adjust width as needed
|
113 |
'white-space': 'normal', # Allows text to wrap to the next line
|
114 |
'word-wrap': 'break-word' # Breaks long words to fit within the width
|
115 |
})
|
116 |
df_gradio = gr.DataFrame(visible=True,
|
117 |
+
value=styled_df,
|
118 |
headers=HEADERS, interactive=False)
|
|
|
|
|
119 |
return df_gradio
|
120 |
|
app/main_multianimal.py
CHANGED
@@ -1,9 +1,10 @@
|
|
1 |
import gradio as gr
|
2 |
from gradio_modal import Modal
|
3 |
|
4 |
-
from validation_submission.create_json import create_json_all_individuals, create_json_one_individual, create_tmp
|
5 |
from validation_submission.add_json import add_data_to_individual
|
6 |
-
from
|
|
|
7 |
from geolocalisation.maps import get_location
|
8 |
from functools import partial
|
9 |
from dead import show_section_dead
|
@@ -15,10 +16,10 @@ from physical.physical_checkbox import on_select_body_part, hide_physical
|
|
15 |
from behavior.behavior_checkbox import show_behavior, on_select_behavior
|
16 |
from follow_up.followup_events import save_fe
|
17 |
from styling.style import *
|
18 |
-
from styling.theme import
|
19 |
-
from classes import Report
|
20 |
|
21 |
-
with gr.Blocks(theme=theme, css=css) as demo:
|
|
|
22 |
create_json_all_individuals()
|
23 |
# ---------------------------------------------------------
|
24 |
# Intro Text
|
@@ -83,18 +84,20 @@ with gr.Blocks(theme=theme, css=css) as demo:
|
|
83 |
|
84 |
# ---------------------------------------------------------
|
85 |
# Initiate sections
|
86 |
-
section_dead,
|
87 |
button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead, \
|
88 |
dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, \
|
|
|
|
|
89 |
fe_collection_dropdown_dead, fe_recepient_dropdown_dead, fe_radio_dropdown_dead, fe_answer_dropdown_dead, \
|
90 |
-
|
91 |
= show_section_dead(False)
|
92 |
-
section_wounded,
|
93 |
button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded, \
|
94 |
dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded, \
|
95 |
behavior_checkbox, behavior_text, \
|
96 |
physical_boxes_wounded, \
|
97 |
-
|
98 |
fe_collection_dropdown_wounded, fe_recepient_dropdown_wounded, fe_radio_dropdown_wounded, fe_answer_dropdown_wounded, \
|
99 |
fe_name_recipient_wounded, fe_collection_ref_wounded \
|
100 |
= show_section_wounded(False)
|
@@ -108,20 +111,23 @@ with gr.Blocks(theme=theme, css=css) as demo:
|
|
108 |
butt_dead.click(partial_show_section_dead,
|
109 |
inputs=None,
|
110 |
outputs=[section_dead,
|
|
|
111 |
button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead,
|
112 |
dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, \
|
|
|
|
|
113 |
fe_collection_dropdown_dead, fe_recepient_dropdown_dead, fe_radio_dropdown_dead, fe_answer_dropdown_dead, \
|
114 |
fe_name_recipient_dead, fe_collection_ref_dead \
|
115 |
])
|
116 |
butt_dead.click(partial_hide_section_wounded,
|
117 |
inputs=None,
|
118 |
outputs=[section_wounded,
|
119 |
-
|
120 |
button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded,
|
121 |
dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded,
|
122 |
behavior_checkbox, behavior_text,
|
123 |
-
physical_boxes_wounded,
|
124 |
-
|
125 |
fe_collection_dropdown_wounded, fe_recepient_dropdown_wounded, fe_radio_dropdown_wounded, fe_answer_dropdown_wounded, \
|
126 |
fe_name_recipient_wounded, fe_collection_ref_wounded \
|
127 |
])
|
@@ -134,25 +140,37 @@ with gr.Blocks(theme=theme, css=css) as demo:
|
|
134 |
butt_wounded.click(partial_show_section_wounded,
|
135 |
inputs=None,
|
136 |
outputs=[section_wounded,
|
137 |
-
|
138 |
button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded,
|
139 |
dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded,
|
140 |
behavior_checkbox, behavior_text,
|
141 |
-
physical_boxes_wounded,
|
142 |
-
|
143 |
fe_collection_dropdown_wounded, fe_recepient_dropdown_wounded, fe_radio_dropdown_wounded, fe_answer_dropdown_wounded, \
|
144 |
fe_name_recipient_wounded, fe_collection_ref_wounded \
|
145 |
])
|
146 |
butt_wounded.click(partial_hide_section_dead, inputs=None, outputs=[section_dead,
|
|
|
147 |
button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead,
|
148 |
dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, \
|
|
|
|
|
149 |
fe_collection_dropdown_dead, fe_recepient_dropdown_dead, fe_radio_dropdown_dead, fe_answer_dropdown_dead, \
|
150 |
fe_name_recipient_dead, fe_collection_ref_dead \
|
151 |
])
|
152 |
-
def save_wounded_state():
|
153 |
-
add_data_tmp("wounded_dead", "wounded", "Yes")
|
154 |
-
butt_wounded.click(save_wounded_state())
|
155 |
# ---------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
156 |
# Dropdowns Dead
|
157 |
button_collision_dead.click(dropdown_collision,
|
158 |
outputs=[dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead])
|
@@ -162,17 +180,42 @@ with gr.Blocks(theme=theme, css=css) as demo:
|
|
162 |
|
163 |
dropdown_dead.select(on_select, None, [dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead])
|
164 |
dropdown_level2_dead.select(on_select_dropdown_level2)
|
165 |
-
openfield_level2_dead.
|
166 |
dropdown_extra_level2_dead.select(on_select_dropdown_extra_level2)
|
167 |
# ---------------------------------------------------------
|
168 |
-
# Radio
|
169 |
-
|
170 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
171 |
outputs=[button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded,
|
172 |
dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded]
|
173 |
)
|
174 |
|
175 |
-
# Dropdowns
|
176 |
button_collision_wounded.click(dropdown_collision,
|
177 |
outputs=[dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded])
|
178 |
button_deliberate_destruction_wounded.click(dropdown_deliberate_destruction, outputs=[dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded])
|
@@ -181,7 +224,7 @@ with gr.Blocks(theme=theme, css=css) as demo:
|
|
181 |
|
182 |
dropdown_wounded.select(on_select, None, [dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded])
|
183 |
dropdown_level2_wounded.select(on_select_dropdown_level2)
|
184 |
-
openfield_level2_wounded.
|
185 |
dropdown_extra_level2_wounded.select(on_select_dropdown_extra_level2)
|
186 |
# ---------------------------------------------------------
|
187 |
# Radio Behavior Wounded
|
@@ -199,17 +242,17 @@ with gr.Blocks(theme=theme, css=css) as demo:
|
|
199 |
# Checkbox Physical Wounded
|
200 |
physical_boxes_wounded.select(find_bounding_box,
|
201 |
inputs=[physical_boxes_wounded, gr.Textbox(value="wounded", visible=False)],
|
202 |
-
outputs=[
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
])
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
|
214 |
# ---------------------------------------------------------
|
215 |
# Follow Up Events Wounded
|
@@ -229,6 +272,10 @@ with gr.Blocks(theme=theme, css=css) as demo:
|
|
229 |
fe_name_recipient_dead.input(save_fe, inputs=[fe_name_recipient_dead, gr.Textbox("recipient name", visible=False)])
|
230 |
fe_collection_ref_dead.input(save_fe, inputs=[fe_collection_ref_dead, gr.Textbox("collection reference", visible=False)])
|
231 |
|
|
|
|
|
|
|
|
|
232 |
# ---------------------------------------------------------
|
233 |
# Add One Individual's Data to the Dataframe
|
234 |
# And Allow clearing of all previous output
|
@@ -238,30 +285,44 @@ with gr.Blocks(theme=theme, css=css) as demo:
|
|
238 |
components=[
|
239 |
camera,
|
240 |
location, identified_location,
|
|
|
|
|
241 |
button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead,
|
242 |
dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead,
|
|
|
|
|
243 |
fe_collection_dropdown_dead, fe_recepient_dropdown_dead, fe_radio_dropdown_dead, fe_answer_dropdown_dead,
|
244 |
fe_name_recipient_dead, fe_collection_ref_dead,
|
245 |
-
|
|
|
246 |
button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded,
|
247 |
dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded,
|
248 |
behavior_checkbox, behavior_text,
|
249 |
physical_boxes_wounded,
|
250 |
-
|
251 |
fe_collection_dropdown_wounded, fe_recepient_dropdown_wounded, fe_radio_dropdown_wounded, fe_answer_dropdown_wounded,
|
252 |
-
fe_name_recipient_wounded, fe_collection_ref_wounded
|
|
|
253 |
])
|
|
|
|
|
|
|
|
|
|
|
254 |
button_clear.click()
|
255 |
button_clear.click(hide_physical,
|
256 |
-
outputs=[
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
|
|
|
|
|
|
263 |
)
|
264 |
-
|
265 |
|
266 |
# ---------------------------------------------------------
|
267 |
# Event Functions of the landing page buttons
|
|
|
1 |
import gradio as gr
|
2 |
from gradio_modal import Modal
|
3 |
|
4 |
+
from validation_submission.create_json import create_json_all_individuals, create_json_one_individual, create_tmp, reset_json
|
5 |
from validation_submission.add_json import add_data_to_individual
|
6 |
+
from validation_submission.validation import reset_error_box
|
7 |
+
from display import save_display_individual
|
8 |
from geolocalisation.maps import get_location
|
9 |
from functools import partial
|
10 |
from dead import show_section_dead
|
|
|
16 |
from behavior.behavior_checkbox import show_behavior, on_select_behavior
|
17 |
from follow_up.followup_events import save_fe
|
18 |
from styling.style import *
|
19 |
+
from styling.theme import css
|
|
|
20 |
|
21 |
+
# with gr.Blocks(theme=theme, css=css) as demo:
|
22 |
+
with gr.Blocks(css=css) as demo:
|
23 |
create_json_all_individuals()
|
24 |
# ---------------------------------------------------------
|
25 |
# Intro Text
|
|
|
84 |
|
85 |
# ---------------------------------------------------------
|
86 |
# Initiate sections
|
87 |
+
section_dead, radio_circumstance_dead, radio_physical_dead,\
|
88 |
button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead, \
|
89 |
dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, \
|
90 |
+
physical_boxes_dead, \
|
91 |
+
checkbox_beak_dead, text_beak_dead, checkbox_body_dead, text_body_dead, checkbox_feathers_dead, text_feathers_dead, checkbox_head_dead, text_head_dead, checkbox_legs_dead, text_legs_dead, \
|
92 |
fe_collection_dropdown_dead, fe_recepient_dropdown_dead, fe_radio_dropdown_dead, fe_answer_dropdown_dead, \
|
93 |
+
fe_name_recipient_dead, fe_collection_ref_dead \
|
94 |
= show_section_dead(False)
|
95 |
+
section_wounded, radio_circumstance_wounded, radio_behavior_wounded, radio_physical_wounded, \
|
96 |
button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded, \
|
97 |
dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded, \
|
98 |
behavior_checkbox, behavior_text, \
|
99 |
physical_boxes_wounded, \
|
100 |
+
checkbox_beak_wounded, text_beak_wounded, checkbox_body_wounded, text_body_wounded, checkbox_feathers_wounded, text_feathers_wounded, checkbox_head_wounded, text_head_wounded, checkbox_legs_wounded, text_legs_wounded, \
|
101 |
fe_collection_dropdown_wounded, fe_recepient_dropdown_wounded, fe_radio_dropdown_wounded, fe_answer_dropdown_wounded, \
|
102 |
fe_name_recipient_wounded, fe_collection_ref_wounded \
|
103 |
= show_section_wounded(False)
|
|
|
111 |
butt_dead.click(partial_show_section_dead,
|
112 |
inputs=None,
|
113 |
outputs=[section_dead,
|
114 |
+
radio_circumstance_dead, radio_physical_dead,
|
115 |
button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead,
|
116 |
dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, \
|
117 |
+
physical_boxes_dead, \
|
118 |
+
checkbox_beak_dead, text_beak_dead, checkbox_body_dead, text_body_dead, checkbox_feathers_dead, text_feathers_dead, checkbox_head_dead, text_head_dead, checkbox_legs_dead, text_legs_dead, \
|
119 |
fe_collection_dropdown_dead, fe_recepient_dropdown_dead, fe_radio_dropdown_dead, fe_answer_dropdown_dead, \
|
120 |
fe_name_recipient_dead, fe_collection_ref_dead \
|
121 |
])
|
122 |
butt_dead.click(partial_hide_section_wounded,
|
123 |
inputs=None,
|
124 |
outputs=[section_wounded,
|
125 |
+
radio_circumstance_wounded, radio_behavior_wounded, radio_physical_wounded,
|
126 |
button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded,
|
127 |
dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded,
|
128 |
behavior_checkbox, behavior_text,
|
129 |
+
physical_boxes_wounded, \
|
130 |
+
checkbox_beak_wounded, text_beak_wounded, checkbox_body_wounded, text_body_wounded, checkbox_feathers_wounded, text_feathers_wounded, checkbox_head_wounded, text_head_wounded, checkbox_legs_wounded, text_legs_wounded, \
|
131 |
fe_collection_dropdown_wounded, fe_recepient_dropdown_wounded, fe_radio_dropdown_wounded, fe_answer_dropdown_wounded, \
|
132 |
fe_name_recipient_wounded, fe_collection_ref_wounded \
|
133 |
])
|
|
|
140 |
butt_wounded.click(partial_show_section_wounded,
|
141 |
inputs=None,
|
142 |
outputs=[section_wounded,
|
143 |
+
radio_circumstance_wounded, radio_behavior_wounded, radio_physical_wounded,
|
144 |
button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded,
|
145 |
dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded,
|
146 |
behavior_checkbox, behavior_text,
|
147 |
+
physical_boxes_wounded, \
|
148 |
+
checkbox_beak_wounded, text_beak_wounded, checkbox_body_wounded, text_body_wounded, checkbox_feathers_wounded, text_feathers_wounded, checkbox_head_wounded, text_head_wounded, checkbox_legs_wounded, text_legs_wounded, \
|
149 |
fe_collection_dropdown_wounded, fe_recepient_dropdown_wounded, fe_radio_dropdown_wounded, fe_answer_dropdown_wounded, \
|
150 |
fe_name_recipient_wounded, fe_collection_ref_wounded \
|
151 |
])
|
152 |
butt_wounded.click(partial_hide_section_dead, inputs=None, outputs=[section_dead,
|
153 |
+
radio_circumstance_dead, radio_physical_dead,
|
154 |
button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead,
|
155 |
dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, \
|
156 |
+
physical_boxes_dead, \
|
157 |
+
checkbox_beak_dead, text_beak_dead, checkbox_body_dead, text_body_dead, checkbox_feathers_dead, text_feathers_dead, checkbox_head_dead, text_head_dead, checkbox_legs_dead, text_legs_dead, \
|
158 |
fe_collection_dropdown_dead, fe_recepient_dropdown_dead, fe_radio_dropdown_dead, fe_answer_dropdown_dead, \
|
159 |
fe_name_recipient_dead, fe_collection_ref_dead \
|
160 |
])
|
|
|
|
|
|
|
161 |
# ---------------------------------------------------------
|
162 |
+
# ---------------------------------------------------------
|
163 |
+
# ---------------------------------------------------------
|
164 |
+
# ---------------------------------------------------------
|
165 |
+
# DEAD
|
166 |
+
# ---------------------------------------------------------
|
167 |
+
# Radio Circumstance Dead
|
168 |
+
radio_circumstance_dead.change(fn=show_circumstances,
|
169 |
+
inputs=[radio_circumstance_dead],
|
170 |
+
outputs=[button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead,
|
171 |
+
dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead]
|
172 |
+
)
|
173 |
+
|
174 |
# Dropdowns Dead
|
175 |
button_collision_dead.click(dropdown_collision,
|
176 |
outputs=[dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead])
|
|
|
180 |
|
181 |
dropdown_dead.select(on_select, None, [dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead])
|
182 |
dropdown_level2_dead.select(on_select_dropdown_level2)
|
183 |
+
openfield_level2_dead.change(on_change_openfield_level2, inputs=[openfield_level2_dead])
|
184 |
dropdown_extra_level2_dead.select(on_select_dropdown_extra_level2)
|
185 |
# ---------------------------------------------------------
|
186 |
+
# Radio Physical Dead
|
187 |
+
radio_physical_dead.change(fn=show_physical,
|
188 |
+
inputs=[radio_physical_dead, gr.Text("dead", visible=False)],
|
189 |
+
outputs=[physical_boxes_dead])
|
190 |
+
|
191 |
+
# Checkbox Physical Dead
|
192 |
+
physical_boxes_dead.select(find_bounding_box,
|
193 |
+
inputs=[physical_boxes_dead, gr.Textbox(value="dead", visible=False)],
|
194 |
+
outputs=[checkbox_beak_dead, text_beak_dead,
|
195 |
+
checkbox_body_dead, text_body_dead,
|
196 |
+
checkbox_feathers_dead, text_feathers_dead,
|
197 |
+
checkbox_head_dead, text_head_dead,
|
198 |
+
checkbox_legs_dead, text_legs_dead
|
199 |
+
])
|
200 |
+
checkbox_beak_dead.select(on_select_body_part, inputs=[checkbox_beak_dead, gr.Text("beak", visible=False)])
|
201 |
+
checkbox_body_dead.select(on_select_body_part, inputs=[checkbox_body_dead, gr.Text("body", visible=False)])
|
202 |
+
checkbox_feathers_dead.select(on_select_body_part, inputs=[checkbox_feathers_dead, gr.Text("feathers", visible=False)])
|
203 |
+
checkbox_head_dead.select(on_select_body_part, inputs=[checkbox_head_dead, gr.Text("head", visible=False)])
|
204 |
+
checkbox_legs_dead.select(on_select_body_part, inputs=[checkbox_legs_dead, gr.Text("legs", visible=False)])
|
205 |
+
# ---------------------------------------------------------
|
206 |
+
# ---------------------------------------------------------
|
207 |
+
# ---------------------------------------------------------
|
208 |
+
# ---------------------------------------------------------
|
209 |
+
# WOUNDED
|
210 |
+
# ---------------------------------------------------------
|
211 |
+
# Radio Circumstance Wounded
|
212 |
+
radio_circumstance_wounded.change(fn=show_circumstances,
|
213 |
+
inputs=[radio_circumstance_wounded],
|
214 |
outputs=[button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded,
|
215 |
dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded]
|
216 |
)
|
217 |
|
218 |
+
# Dropdowns Circumstance Wounded
|
219 |
button_collision_wounded.click(dropdown_collision,
|
220 |
outputs=[dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded])
|
221 |
button_deliberate_destruction_wounded.click(dropdown_deliberate_destruction, outputs=[dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded])
|
|
|
224 |
|
225 |
dropdown_wounded.select(on_select, None, [dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded])
|
226 |
dropdown_level2_wounded.select(on_select_dropdown_level2)
|
227 |
+
openfield_level2_wounded.change(on_change_openfield_level2, inputs=[openfield_level2_wounded])
|
228 |
dropdown_extra_level2_wounded.select(on_select_dropdown_extra_level2)
|
229 |
# ---------------------------------------------------------
|
230 |
# Radio Behavior Wounded
|
|
|
242 |
# Checkbox Physical Wounded
|
243 |
physical_boxes_wounded.select(find_bounding_box,
|
244 |
inputs=[physical_boxes_wounded, gr.Textbox(value="wounded", visible=False)],
|
245 |
+
outputs=[checkbox_beak_wounded, text_beak_wounded,
|
246 |
+
checkbox_body_wounded, text_body_wounded,
|
247 |
+
checkbox_feathers_wounded, text_feathers_wounded,
|
248 |
+
checkbox_head_wounded, text_head_wounded,
|
249 |
+
checkbox_legs_wounded, text_legs_wounded
|
250 |
])
|
251 |
+
checkbox_beak_wounded.select(on_select_body_part, inputs=[checkbox_beak_wounded, gr.Text("beak", visible=False)])
|
252 |
+
checkbox_body_wounded.select(on_select_body_part, inputs=[checkbox_body_wounded, gr.Text("body", visible=False)])
|
253 |
+
checkbox_feathers_wounded.select(on_select_body_part, inputs=[checkbox_feathers_wounded, gr.Text("feathers", visible=False)])
|
254 |
+
checkbox_head_wounded.select(on_select_body_part, inputs=[checkbox_head_wounded, gr.Text("head", visible=False)])
|
255 |
+
checkbox_legs_wounded.select(on_select_body_part, inputs=[checkbox_legs_wounded, gr.Text("legs", visible=False)])
|
256 |
|
257 |
# ---------------------------------------------------------
|
258 |
# Follow Up Events Wounded
|
|
|
272 |
fe_name_recipient_dead.input(save_fe, inputs=[fe_name_recipient_dead, gr.Textbox("recipient name", visible=False)])
|
273 |
fe_collection_ref_dead.input(save_fe, inputs=[fe_collection_ref_dead, gr.Textbox("collection reference", visible=False)])
|
274 |
|
275 |
+
# ---------------------------------------------------------
|
276 |
+
# Error Box
|
277 |
+
error_box = gr.Text(value=None, visible=False)
|
278 |
+
|
279 |
# ---------------------------------------------------------
|
280 |
# Add One Individual's Data to the Dataframe
|
281 |
# And Allow clearing of all previous output
|
|
|
285 |
components=[
|
286 |
camera,
|
287 |
location, identified_location,
|
288 |
+
#dead reset
|
289 |
+
radio_circumstance_dead, radio_physical_dead,
|
290 |
button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead,
|
291 |
dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead,
|
292 |
+
physical_boxes_dead,
|
293 |
+
checkbox_beak_dead, text_beak_dead, checkbox_body_dead, text_body_dead, checkbox_feathers_dead, text_feathers_dead, checkbox_head_dead, text_head_dead, checkbox_legs_dead, text_legs_dead,
|
294 |
fe_collection_dropdown_dead, fe_recepient_dropdown_dead, fe_radio_dropdown_dead, fe_answer_dropdown_dead,
|
295 |
fe_name_recipient_dead, fe_collection_ref_dead,
|
296 |
+
#wounded reset
|
297 |
+
radio_circumstance_wounded, radio_behavior_wounded, radio_physical_wounded,
|
298 |
button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded,
|
299 |
dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded,
|
300 |
behavior_checkbox, behavior_text,
|
301 |
physical_boxes_wounded,
|
302 |
+
checkbox_beak_wounded, text_beak_wounded, checkbox_body_wounded, text_body_wounded, checkbox_feathers_wounded, text_feathers_wounded, checkbox_head_wounded, text_head_wounded, checkbox_legs_wounded, text_legs_wounded,
|
303 |
fe_collection_dropdown_wounded, fe_recepient_dropdown_wounded, fe_radio_dropdown_wounded, fe_answer_dropdown_wounded,
|
304 |
+
fe_name_recipient_wounded, fe_collection_ref_wounded,
|
305 |
+
error_box
|
306 |
])
|
307 |
+
button_close = gr.Button("Back to Display", scale = 1)
|
308 |
+
|
309 |
+
|
310 |
+
# ---------------------------------------------------------
|
311 |
+
# Button Click Logic
|
312 |
button_clear.click()
|
313 |
button_clear.click(hide_physical,
|
314 |
+
outputs=[checkbox_beak_wounded, text_beak_wounded, checkbox_body_wounded, text_body_wounded, checkbox_feathers_wounded, text_feathers_wounded, checkbox_head_wounded, text_head_wounded, checkbox_legs_wounded, text_legs_wounded])
|
315 |
+
button_clear.click(hide_physical,
|
316 |
+
outputs=[checkbox_beak_dead, text_beak_dead, checkbox_body_dead, text_body_dead, checkbox_feathers_dead, text_feathers_dead, checkbox_head_dead, text_head_dead, checkbox_legs_dead, text_legs_dead])
|
317 |
+
|
318 |
+
button_clear.click(reset_error_box, inputs=[error_box], outputs=[error_box])
|
319 |
+
button_clear.click(reset_json)
|
320 |
+
|
321 |
+
button_df.click(save_display_individual,
|
322 |
+
inputs=[gallery, df, error_box],
|
323 |
+
outputs=[gallery, df, error_box]
|
324 |
)
|
325 |
+
button_close.click(lambda: Modal(visible=False), None, modal)
|
326 |
|
327 |
# ---------------------------------------------------------
|
328 |
# Event Functions of the landing page buttons
|
app/styling/style.py
CHANGED
@@ -3,7 +3,7 @@ import gradio as gr
|
|
3 |
gr.HTML('''
|
4 |
<style>
|
5 |
.custom-button {
|
6 |
-
background-color: #
|
7 |
border: none;
|
8 |
color: white;
|
9 |
padding: 15px 32px;
|
@@ -16,4 +16,22 @@ gr.HTML('''
|
|
16 |
border-radius: 8px;
|
17 |
}
|
18 |
</style>
|
19 |
-
''')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
gr.HTML('''
|
4 |
<style>
|
5 |
.custom-button {
|
6 |
+
background-color: #3B4C54;
|
7 |
border: none;
|
8 |
color: white;
|
9 |
padding: 15px 32px;
|
|
|
16 |
border-radius: 8px;
|
17 |
}
|
18 |
</style>
|
19 |
+
''')
|
20 |
+
|
21 |
+
# gr.HTML('''
|
22 |
+
# <style>
|
23 |
+
# .custom-button {
|
24 |
+
# background-color: #4CAF50; /* Green */
|
25 |
+
# border: none;
|
26 |
+
# color: white;
|
27 |
+
# padding: 15px 32px;
|
28 |
+
# text-align: center;
|
29 |
+
# text-decoration: none;
|
30 |
+
# display: inline-block;
|
31 |
+
# font-size: 16px;
|
32 |
+
# margin: 4px 2px;
|
33 |
+
# cursor: pointer;
|
34 |
+
# border-radius: 8px;
|
35 |
+
# }
|
36 |
+
# </style>
|
37 |
+
# ''')
|
app/styling/theme.py
CHANGED
@@ -2,17 +2,103 @@ import gradio as gr
|
|
2 |
|
3 |
css = """
|
4 |
.gradio-container {background: url(https://openclipart.org/image/2000px/279687)}
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
#
|
10 |
-
|
11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
#submit {background-color: #abb2bf}
|
|
|
|
|
13 |
"""
|
14 |
|
15 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
|
17 |
-
theme = gr.themes.Soft(primary_hue="teal", secondary_hue="teal", neutral_hue="emerald",
|
18 |
-
|
|
|
2 |
|
3 |
css = """
|
4 |
.gradio-container {background: url(https://openclipart.org/image/2000px/279687)}
|
5 |
+
|
6 |
+
/* Main background */
|
7 |
+
body {
|
8 |
+
background-color: #3B4C54;
|
9 |
+
color: #ffffff; /* Set default text color for contrast */
|
10 |
+
}
|
11 |
+
|
12 |
+
/* Secondary color for headers and panels */
|
13 |
+
.gradio-container .card,
|
14 |
+
.gradio-container h1,
|
15 |
+
.gradio-container h2,
|
16 |
+
.gradio-container h3,
|
17 |
+
.gradio-container h4 {
|
18 |
+
background-color: #3F543B;
|
19 |
+
color: #ffffff; /* Ensuring text is readable */
|
20 |
+
}
|
21 |
+
|
22 |
+
|
23 |
+
|
24 |
+
|
25 |
+
/* Background color for the wounded section */
|
26 |
+
#wounded {
|
27 |
+
background-color: #503B54;
|
28 |
+
color: #ffffff; /* Ensures text is readable */
|
29 |
+
}
|
30 |
+
|
31 |
+
/* Olive green color for headers within the wounded section */
|
32 |
+
#wounded h1,
|
33 |
+
#wounded h2,
|
34 |
+
#wounded h3,
|
35 |
+
#wounded h4,
|
36 |
+
#wounded h5,
|
37 |
+
#wounded h6 {
|
38 |
+
color: #ffffff; /* Olive green color for header text */
|
39 |
+
background-color: #503B54; /* No background color for headers */
|
40 |
+
}
|
41 |
+
|
42 |
+
/* Styling dropdowns within the wounded section */
|
43 |
+
#wounded select {
|
44 |
+
background-color: #3F543B; /* Olive green background */
|
45 |
+
color: #ffffff; /* Ensures text is readable */
|
46 |
+
border: 1px solid #3B4C54; /* Optional border for consistency */
|
47 |
+
}
|
48 |
+
|
49 |
+
/* Styling checkboxes within the wounded section */
|
50 |
+
#wounded input[type="checkbox"] {
|
51 |
+
accent-color: #3F543B; /* Olive green color for the checkbox */
|
52 |
+
}
|
53 |
+
|
54 |
+
/* Additional checkbox label styling if needed */
|
55 |
+
#wounded label {
|
56 |
+
color: #ffffff; /* Ensures labels are readable */
|
57 |
+
}
|
58 |
+
|
59 |
+
|
60 |
+
|
61 |
+
|
62 |
+
|
63 |
+
/* Background color for the dead section */
|
64 |
+
#dead {
|
65 |
+
background-color: #54433B;
|
66 |
+
color: #ffffff; /* Ensures text is readable */
|
67 |
+
}
|
68 |
+
|
69 |
+
/* Brown color for headers within the dead section */
|
70 |
+
#dead h1,
|
71 |
+
#dead h2,
|
72 |
+
#dead h3,
|
73 |
+
#dead h4,
|
74 |
+
#dead h5,
|
75 |
+
#dead h6 {
|
76 |
+
color: #ffffff; /* Olive green color for header text */
|
77 |
+
background-color: #54433B; /* No background color for headers */
|
78 |
+
}
|
79 |
+
|
80 |
+
|
81 |
+
#bird-boxes {background-color: #3B4C54}
|
82 |
#submit {background-color: #abb2bf}
|
83 |
+
#error {background-color: #e82323}
|
84 |
+
#valid {background-color: #07e63f}
|
85 |
"""
|
86 |
|
87 |
+
# OLD THEME:
|
88 |
+
|
89 |
+
# css = """
|
90 |
+
# .gradio-container {background: url(https://openclipart.org/image/2000px/279687)}
|
91 |
+
# #image {background-color: #73b9ae}
|
92 |
+
# #dead {background-color: #333333}
|
93 |
+
# #wounded {background-color: #5e0724}
|
94 |
+
# #bird-boxes {background-color: #f2f3f3}
|
95 |
+
# #buttons-conditions {background-color: #b3b3b3}
|
96 |
+
# #dropdown-conditions {background-color: #b3b3b3}
|
97 |
+
# #followup {background-color: #38241c}
|
98 |
+
# #submit {background-color: #abb2bf}
|
99 |
+
# #error {background-color: #e82323}
|
100 |
+
# #valid {background-color: #07e63f}
|
101 |
+
# """
|
102 |
|
103 |
+
# theme = gr.themes.Soft(primary_hue="teal", secondary_hue="teal", neutral_hue="emerald",
|
104 |
+
# font=[gr.themes.GoogleFont("Inconsolata"), "Arial", "sans-serif"])
|
app/validation_submission/create_json.py
CHANGED
@@ -13,4 +13,8 @@ def create_json_all_individuals(all_individuals={}):
|
|
13 |
def create_tmp(tmp_name="wounded_dead", tmp={}):
|
14 |
tmp = json.dumps(tmp)
|
15 |
with open(f"app/assets/tmp_json/tmp_{tmp_name}.json", "w") as outfile:
|
16 |
-
outfile.write(tmp)
|
|
|
|
|
|
|
|
|
|
13 |
def create_tmp(tmp_name="wounded_dead", tmp={}):
|
14 |
tmp = json.dumps(tmp)
|
15 |
with open(f"app/assets/tmp_json/tmp_{tmp_name}.json", "w") as outfile:
|
16 |
+
outfile.write(tmp)
|
17 |
+
|
18 |
+
def reset_json():
|
19 |
+
create_json_one_individual()
|
20 |
+
create_tmp()
|
app/validation_submission/processing.py
CHANGED
@@ -11,26 +11,9 @@ def process_circumstance(data):
|
|
11 |
key = data["circumstance_type"][field+"_label"]
|
12 |
data["circumstance_type"][key] = val
|
13 |
data["circumstance_type"].pop(field+"_label")
|
14 |
-
# {"circumstance_radio": true,
|
15 |
-
# "circumstance": "destruction / deliberatly removed",
|
16 |
-
# "cirumstance_type": {"type": "removal or direct capture",
|
17 |
-
# "option_dropdown_label": "method",
|
18 |
-
# "open_field_label": "NA",
|
19 |
-
# "extra_label": "NA"},
|
20 |
-
# "circumstance_option_dropdown": "Traffic/Trade"}
|
21 |
return data
|
22 |
|
23 |
def process_behaviors(data):
|
24 |
-
# INPUT :
|
25 |
-
#"behaviors_radio": true,
|
26 |
-
# "behaviors_type": ["Crash, Falling From The Sky", "Neurological"]
|
27 |
-
#OUTPUT:
|
28 |
-
# "behaviors_radio": "Yes",
|
29 |
-
# "behaviors_type": [
|
30 |
-
# {
|
31 |
-
# "type": "abnormal breathing",
|
32 |
-
# "description": "Problems breathing, breathing sounds"
|
33 |
-
# }
|
34 |
behaviors =[]
|
35 |
if data["behaviors_radio"] == "Yes":
|
36 |
for type in data["behaviors_type"]:
|
@@ -41,21 +24,6 @@ def process_behaviors(data):
|
|
41 |
return data
|
42 |
|
43 |
def process_physical(data):
|
44 |
-
# INPUT
|
45 |
-
# "physical_type_feathers": "feathers",
|
46 |
-
# "physical_anomaly_type_feathers": ["Blood", "Swelling"]}
|
47 |
-
|
48 |
-
# OUTPUT
|
49 |
-
# "physical_radio": "Yes",
|
50 |
-
# "physical_anomalies_type": [
|
51 |
-
# {
|
52 |
-
# "type": "beak",
|
53 |
-
# "anomaly_type": "deformation"
|
54 |
-
# },
|
55 |
-
# {
|
56 |
-
# "type": "body",
|
57 |
-
# "anomaly_type": "fluffed up"
|
58 |
-
# },
|
59 |
body_parts= ["beak", "body", "legs", "feathers/wings/tail", "head incl. eyes"]
|
60 |
anomalies=[]
|
61 |
reformatted = {}
|
@@ -74,29 +42,6 @@ def process_physical(data):
|
|
74 |
return reformatted
|
75 |
|
76 |
def process_followup(data):
|
77 |
-
# "follow_up_events": [
|
78 |
-
# {
|
79 |
-
# "type": "animal collected",
|
80 |
-
# "option": "Yes"
|
81 |
-
# },
|
82 |
-
# {
|
83 |
-
# "type": "recipient",
|
84 |
-
# "option": "Veterinary",
|
85 |
-
# "name_recipient": "Dr. Jane Smith"
|
86 |
-
# },
|
87 |
-
# {
|
88 |
-
# "type": "radiography",
|
89 |
-
# "option": "Unknown"
|
90 |
-
# },
|
91 |
-
# {
|
92 |
-
# "type": "given answer",
|
93 |
-
# "option": "Discussion with the speaker"
|
94 |
-
# },
|
95 |
-
# {
|
96 |
-
# "type": "collection reference",
|
97 |
-
# "reference": "Specimen ID: 12345, Collected on 2023-09-15"
|
98 |
-
# }
|
99 |
-
# ]
|
100 |
followup_events = []
|
101 |
for key, val in data.items():
|
102 |
followup_event={}
|
|
|
11 |
key = data["circumstance_type"][field+"_label"]
|
12 |
data["circumstance_type"][key] = val
|
13 |
data["circumstance_type"].pop(field+"_label")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
return data
|
15 |
|
16 |
def process_behaviors(data):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
behaviors =[]
|
18 |
if data["behaviors_radio"] == "Yes":
|
19 |
for type in data["behaviors_type"]:
|
|
|
24 |
return data
|
25 |
|
26 |
def process_physical(data):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
body_parts= ["beak", "body", "legs", "feathers/wings/tail", "head incl. eyes"]
|
28 |
anomalies=[]
|
29 |
reformatted = {}
|
|
|
42 |
return reformatted
|
43 |
|
44 |
def process_followup(data):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
followup_events = []
|
46 |
for key, val in data.items():
|
47 |
followup_event={}
|
app/validation_submission/submission.py
CHANGED
@@ -2,10 +2,11 @@ import json
|
|
2 |
from validation_submission.get_json import get_json_all_individuals
|
3 |
from validation_submission.validation import validate_individual
|
4 |
|
5 |
-
def validate_save_individual():
|
6 |
-
individual = validate_individual()
|
7 |
-
|
8 |
-
|
|
|
9 |
|
10 |
def save_to_all_individuals(one_individual):
|
11 |
all_individuals = get_json_all_individuals()
|
|
|
2 |
from validation_submission.get_json import get_json_all_individuals
|
3 |
from validation_submission.validation import validate_individual
|
4 |
|
5 |
+
def validate_save_individual(error_box):
|
6 |
+
individual, error_box = validate_individual(error_box)
|
7 |
+
if individual:
|
8 |
+
save_to_all_individuals(individual.model_dump())
|
9 |
+
return individual, error_box
|
10 |
|
11 |
def save_to_all_individuals(one_individual):
|
12 |
all_individuals = get_json_all_individuals()
|
app/validation_submission/validation.py
CHANGED
@@ -1,4 +1,6 @@
|
|
1 |
import uuid
|
|
|
|
|
2 |
|
3 |
from validation_submission.get_json import get_json_tmp, get_json_one_individual
|
4 |
from circumstances.class_circumstance import Circumstances
|
@@ -15,66 +17,129 @@ def get_fields(data_dict, keyword):
|
|
15 |
extract[key] = val
|
16 |
return extract
|
17 |
|
18 |
-
def validate_individual():
|
|
|
19 |
data = get_json_one_individual()
|
20 |
data["identifier"] = str(uuid.uuid4())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
if "wounded_state" not in data or "dead_state" not in data:
|
22 |
data["wounded_state"] = "No"
|
23 |
data["dead_state"] = "No"
|
24 |
if (data["wounded_state"] == "Yes") or (data["dead_state"] == "Yes"):
|
25 |
data_wounded_dead = get_json_tmp("wounded_dead")
|
26 |
-
circumstance = validate_circumstance(data_wounded_dead)
|
27 |
-
physical = validate_physical(data_wounded_dead)
|
28 |
-
followup = validate_follow_up(data_wounded_dead)
|
29 |
|
30 |
if data["wounded_state"]=="Yes":
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
elif data["dead_state"]=="Yes":
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
|
|
|
|
|
|
|
|
51 |
else:
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
|
|
|
|
|
|
|
60 |
|
61 |
#### VALIDATION FUNCTIONS
|
62 |
def validate_circumstance(data):
|
63 |
circumstance_raw = get_fields(data, "circumstance")
|
64 |
circumstance_formatted = process_circumstance(circumstance_raw)
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
|
70 |
def validate_behavior(data):
|
71 |
behaviors_raw = get_fields(data, "behaviors")
|
72 |
behaviors_formatted = process_behaviors(behaviors_raw)
|
73 |
try:
|
74 |
Behaviors.model_validate(behaviors_formatted)
|
75 |
-
|
76 |
-
|
|
|
|
|
77 |
print("Validation failed for the behaviors.")
|
|
|
|
|
|
|
78 |
|
79 |
|
80 |
def validate_physical(data):
|
@@ -82,18 +147,27 @@ def validate_physical(data):
|
|
82 |
physical_formatted = process_physical(physical_raw)
|
83 |
try:
|
84 |
PhysicalAnomalies.model_validate(physical_formatted)
|
85 |
-
|
86 |
-
|
|
|
|
|
87 |
print("Validation failed for the physical anomalies.")
|
|
|
|
|
|
|
88 |
|
89 |
def validate_follow_up(data):
|
90 |
followup_raw = get_fields(data, "followup")
|
91 |
followup_formatted = process_followup(followup_raw)
|
92 |
try:
|
93 |
FollowUpEvents.model_validate(followup_formatted)
|
94 |
-
|
95 |
-
|
|
|
|
|
96 |
print("Validation failed for the follow-up events.")
|
|
|
|
|
97 |
|
98 |
|
99 |
|
|
|
1 |
import uuid
|
2 |
+
from pydantic import ValidationError
|
3 |
+
import gradio as gr
|
4 |
|
5 |
from validation_submission.get_json import get_json_tmp, get_json_one_individual
|
6 |
from circumstances.class_circumstance import Circumstances
|
|
|
17 |
extract[key] = val
|
18 |
return extract
|
19 |
|
20 |
+
def validate_individual(error_box):
|
21 |
+
error_box = reset_error_box(error_box)
|
22 |
data = get_json_one_individual()
|
23 |
data["identifier"] = str(uuid.uuid4())
|
24 |
+
if "image" in data.keys():
|
25 |
+
img = ImageBase64.to_base64(data["image"])
|
26 |
+
else:
|
27 |
+
img = None
|
28 |
+
if "geolocalisation" in data.keys():
|
29 |
+
geolocalisation = data["geolocalisation"]
|
30 |
+
else:
|
31 |
+
geolocalisation = None
|
32 |
+
|
33 |
+
error_behavior = None
|
34 |
+
error_circumstance = None
|
35 |
+
error_followup = None
|
36 |
+
error_physical = None
|
37 |
+
error_individual = None
|
38 |
if "wounded_state" not in data or "dead_state" not in data:
|
39 |
data["wounded_state"] = "No"
|
40 |
data["dead_state"] = "No"
|
41 |
if (data["wounded_state"] == "Yes") or (data["dead_state"] == "Yes"):
|
42 |
data_wounded_dead = get_json_tmp("wounded_dead")
|
43 |
+
circumstance, error_circumstance = validate_circumstance(data_wounded_dead)
|
44 |
+
physical, error_physical = validate_physical(data_wounded_dead)
|
45 |
+
followup, error_followup = validate_follow_up(data_wounded_dead)
|
46 |
|
47 |
if data["wounded_state"]=="Yes":
|
48 |
+
print(physical)
|
49 |
+
behavior, error_behavior = validate_behavior(data_wounded_dead)
|
50 |
+
try :
|
51 |
+
individual = Report(identifier = data["identifier"],
|
52 |
+
image = img,
|
53 |
+
geolocalisation = geolocalisation,
|
54 |
+
wounded_state = data["wounded_state"],
|
55 |
+
wounded = Wounded(circumstances = circumstance,
|
56 |
+
behaviors = behavior,
|
57 |
+
physical_anomalies = physical,
|
58 |
+
follow_up_events = followup),
|
59 |
+
dead_state = data["dead_state"])
|
60 |
+
except ValidationError as e:
|
61 |
+
print(e)
|
62 |
+
error_individual = e
|
63 |
+
|
64 |
elif data["dead_state"]=="Yes":
|
65 |
+
try:
|
66 |
+
individual = Report(identifier = data["identifier"],
|
67 |
+
image = img,
|
68 |
+
geolocalisation = geolocalisation,
|
69 |
+
wounded_state = data["wounded_state"],
|
70 |
+
dead_state = data["dead_state"],
|
71 |
+
dead = Dead(circumstances = circumstance,
|
72 |
+
physical_anomalies = physical,
|
73 |
+
follow_up_events = followup)
|
74 |
+
)
|
75 |
+
except ValidationError as e:
|
76 |
+
print(e)
|
77 |
+
error_individual = e
|
78 |
else:
|
79 |
+
try:
|
80 |
+
individual = Report(identifier = data["identifier"],
|
81 |
+
image = img,
|
82 |
+
geolocalisation = geolocalisation,
|
83 |
+
wounded_state = data["wounded_state"],
|
84 |
+
dead_state = data["dead_state"])
|
85 |
+
except ValidationError as e:
|
86 |
+
print(e)
|
87 |
+
error_individual = e
|
88 |
+
if error_behavior or error_circumstance or error_followup or error_physical or error_individual:
|
89 |
+
error_box = show_error(error_box, error_behavior, error_circumstance, error_followup, error_physical, error_individual)
|
90 |
+
individual = None
|
91 |
+
else:
|
92 |
+
error_box= gr.Text(label="ALL VALID.", value="Record Registered. You can return to the Display.", visible=True, elem_id="valid")
|
93 |
+
return individual, error_box
|
94 |
|
95 |
+
def show_error(error_box, error_behavior, error_circumstance, error_followup, error_physical, error_individual):
|
96 |
+
error_text = ""
|
97 |
+
if error_circumstance:
|
98 |
+
error_text += f"Error in circumstance: {error_circumstance}\n"
|
99 |
+
if error_behavior:
|
100 |
+
error_text += f"Error in behavior: {error_behavior}\n"
|
101 |
+
if error_physical:
|
102 |
+
error_text += f"Error in physical: {error_physical}\n"
|
103 |
+
if error_followup:
|
104 |
+
error_text += f"Error in follow-up: {error_followup}\n"
|
105 |
+
if error_individual:
|
106 |
+
error_text += f"Error in individual: {error_individual}\n"
|
107 |
+
error_text += "PLEASE CORRECT THESE ERRORS BEFORE SUBMITTING."
|
108 |
+
error_box= gr.Text(label="ERROR DETECTED !", value=error_text, visible=True, elem_id="error")
|
109 |
+
return error_box
|
110 |
|
111 |
+
def reset_error_box(error_box):
|
112 |
+
error_box = gr.Text(value=None, visible=False)
|
113 |
+
return error_box
|
114 |
|
115 |
#### VALIDATION FUNCTIONS
|
116 |
def validate_circumstance(data):
|
117 |
circumstance_raw = get_fields(data, "circumstance")
|
118 |
circumstance_formatted = process_circumstance(circumstance_raw)
|
119 |
+
try:
|
120 |
+
Circumstances.model_validate(circumstance_formatted)
|
121 |
+
circumstances = Circumstances(**circumstance_formatted)
|
122 |
+
error = None
|
123 |
+
except ValidationError as e:
|
124 |
+
error = e
|
125 |
+
print(e)
|
126 |
+
circumstances = None
|
127 |
+
return circumstances, error
|
128 |
+
|
129 |
|
130 |
def validate_behavior(data):
|
131 |
behaviors_raw = get_fields(data, "behaviors")
|
132 |
behaviors_formatted = process_behaviors(behaviors_raw)
|
133 |
try:
|
134 |
Behaviors.model_validate(behaviors_formatted)
|
135 |
+
behavior = Behaviors(**behaviors_formatted)
|
136 |
+
error = None
|
137 |
+
except ValidationError as e:
|
138 |
+
print(e)
|
139 |
print("Validation failed for the behaviors.")
|
140 |
+
behavior = None
|
141 |
+
error = e
|
142 |
+
return behavior, error
|
143 |
|
144 |
|
145 |
def validate_physical(data):
|
|
|
147 |
physical_formatted = process_physical(physical_raw)
|
148 |
try:
|
149 |
PhysicalAnomalies.model_validate(physical_formatted)
|
150 |
+
physical = PhysicalAnomalies(**physical_formatted)
|
151 |
+
error = None
|
152 |
+
except ValidationError as e:
|
153 |
+
print(e)
|
154 |
print("Validation failed for the physical anomalies.")
|
155 |
+
physical = None
|
156 |
+
error = e
|
157 |
+
return physical, error
|
158 |
|
159 |
def validate_follow_up(data):
|
160 |
followup_raw = get_fields(data, "followup")
|
161 |
followup_formatted = process_followup(followup_raw)
|
162 |
try:
|
163 |
FollowUpEvents.model_validate(followup_formatted)
|
164 |
+
followup = FollowUpEvents(**followup_formatted)
|
165 |
+
error = None
|
166 |
+
except ValidationError as e:
|
167 |
+
print(e)
|
168 |
print("Validation failed for the follow-up events.")
|
169 |
+
followup = None
|
170 |
+
return followup, error
|
171 |
|
172 |
|
173 |
|