caviri commited on
Commit
baec762
·
1 Parent(s): 629cbaa

feat(JSON): individual JSON swapped by gradio state to avoid multiuser overwritting issues

Browse files
README.md CHANGED
@@ -12,32 +12,36 @@ short_description: Digiwild
12
 
13
  ## Docker
14
 
15
- ```
16
  docker build -t ordes/digiwild .
17
  ```
18
 
19
 
20
- ```
21
- docker run -it -p 7860:7860 ordes/digiwild:swallow
22
  ```
23
 
24
- ```
25
  cd /digiwild/app
26
  python3 main.py
27
  ```
28
 
29
  ### How to develop on docker
30
 
31
- ```
32
- docker run -it -p 7860:3333 -v $(pwd):/home/user/digiwild/
33
  ```
34
 
35
  ## TODO
36
 
 
 
37
  - [ ] Use in memory object instead of files to avoid writting / reading problems.
38
  - [ ] Connection to a database? Maybe an open MongoDB
39
- - [ ] GPS Compatibility
40
- - [ ] New fields suggested
 
 
41
 
42
  ## Needs
43
 
@@ -45,4 +49,6 @@ docker run -it -p 7860:3333 -v $(pwd):/home/user/digiwild/
45
  - Uploading of pics
46
  - GPS location
47
  - Comments
48
- - Symptomps selection (Dropdown)
 
 
 
12
 
13
  ## Docker
14
 
15
+ ``` bash
16
  docker build -t ordes/digiwild .
17
  ```
18
 
19
 
20
+ ``` bash
21
+ docker run -it -p 7860:7860 ordes/digiwild
22
  ```
23
 
24
+ ``` bash
25
  cd /digiwild/app
26
  python3 main.py
27
  ```
28
 
29
  ### How to develop on docker
30
 
31
+ ``` bash
32
+ docker run -it -p 7860:7860 -v $(pwd):/home/user/digiwild/ ordes/digiwild
33
  ```
34
 
35
  ## TODO
36
 
37
+ - [x] Change `wounded` to `wounded / sick`
38
+ - [x] Info formatting
39
  - [ ] Use in memory object instead of files to avoid writting / reading problems.
40
  - [ ] Connection to a database? Maybe an open MongoDB
41
+ - [x] GPS Compatibility
42
+ - [x] New fields suggested: Number individuals, Species, Comments
43
+ - [ ] Save new fields values into the JSON. Perform validation too.
44
+ - [ ] Add info and placeholder information to the different components.
45
 
46
  ## Needs
47
 
 
49
  - Uploading of pics
50
  - GPS location
51
  - Comments
52
+ - Symptomps selection (Dropdown)
53
+
54
+ ## PR Updates
app/behavior/behavior_checkbox.py CHANGED
@@ -4,9 +4,10 @@ from utils.utils_checkbox import create_checkbox
4
  from utils.utils_visible import set_visible
5
  from validation_submission.add_json import add_data_tmp
6
 
7
- def on_select_behavior(behavior_checkbox):
8
  behavior_checkbox = [behavior.lower() for behavior in behavior_checkbox]
9
- add_data_tmp("wounded_dead", "behaviors_type", behavior_checkbox)
 
10
 
11
  def retrieve_behavior_options_description():
12
  dropdown_config = get_custom_config_dropdowns("config_checkbox_behavior.json")
@@ -23,8 +24,8 @@ def create_behavior_checkbox(section: str, visible):
23
  checkbox, text = create_checkbox("", section, label_checkbox, visible, options, descriptions)
24
  return checkbox, text
25
 
26
- def show_behavior(choice, section: str):
27
  visible = set_visible(choice)
28
  checkbox, text = create_behavior_checkbox(section, visible)
29
- add_data_tmp("wounded_dead", "behaviors_radio", choice)
30
- return checkbox, text
 
4
  from utils.utils_visible import set_visible
5
  from validation_submission.add_json import add_data_tmp
6
 
7
+ def on_select_behavior(behavior_checkbox, individual):
8
  behavior_checkbox = [behavior.lower() for behavior in behavior_checkbox]
9
+ individual = add_data_tmp("wounded_dead", "behaviors_type", behavior_checkbox)
10
+ return individual
11
 
12
  def retrieve_behavior_options_description():
13
  dropdown_config = get_custom_config_dropdowns("config_checkbox_behavior.json")
 
24
  checkbox, text = create_checkbox("", section, label_checkbox, visible, options, descriptions)
25
  return checkbox, text
26
 
27
+ def show_behavior(choice, section: str, individual):
28
  visible = set_visible(choice)
29
  checkbox, text = create_behavior_checkbox(section, visible)
30
+ individual = add_data_tmp("wounded_dead", "behaviors_radio", choice, individual)
31
+ return checkbox, text, individual
app/circumstances/circumstances.py CHANGED
@@ -13,13 +13,13 @@ LOGO_PATH = PATH + PATH_ASSETS + "logos"
13
  CAUSE_COL_WIDTH = "50px"
14
 
15
 
16
- def show_circumstances(choice):
17
  visible = set_visible(choice)
18
- add_data_tmp("wounded_dead",
19
  "circumstance_radio",
20
- choice)
21
  button_collision, button_deliberate_destruction, button_indirect_destruction, button_natural_cause, dropdown, dropdown_level2, openfield_level2, dropdown_extra_level2 = create_circumstances(visible)
22
- return button_collision, button_deliberate_destruction, button_indirect_destruction, button_natural_cause, dropdown, dropdown_level2, openfield_level2, dropdown_extra_level2
23
 
24
  def create_circumstances(visible):
25
  button_collision, button_deliberate_destruction, button_indirect_destruction, button_natural_cause = create_circumstances_buttons(visible)
 
13
  CAUSE_COL_WIDTH = "50px"
14
 
15
 
16
+ def show_circumstances(choice, individual):
17
  visible = set_visible(choice)
18
+ individual = add_data_tmp("wounded_dead",
19
  "circumstance_radio",
20
+ choice, individual)
21
  button_collision, button_deliberate_destruction, button_indirect_destruction, button_natural_cause, dropdown, dropdown_level2, openfield_level2, dropdown_extra_level2 = create_circumstances(visible)
22
+ return button_collision, button_deliberate_destruction, button_indirect_destruction, button_natural_cause, dropdown, dropdown_level2, openfield_level2, dropdown_extra_level2, individual
23
 
24
  def create_circumstances(visible):
25
  button_collision, button_deliberate_destruction, button_indirect_destruction, button_natural_cause = create_circumstances_buttons(visible)
app/circumstances/circumstances_dropdowns.py CHANGED
@@ -14,32 +14,32 @@ def reinitialise_level2():
14
  dropdown_extra_level2 = gr.Dropdown(choices=[], visible=False)
15
  return dropdown_level2, openfield_level2, dropdown_extra_level2
16
 
17
- def create_dropdown_level1(label):
18
  dropdown_config = get_custom_config_dropdowns("config_dropdown_circumstances.json")
19
  options = retrieve_config_options(label, dropdown_config)
20
  dropdown = gr.Dropdown(choices=options, label=label, interactive=True, visible=True)
21
  dropdown_level2, openfield_level2, dropdown_extra_level2 = reinitialise_level2()
22
- return dropdown, dropdown_level2, openfield_level2, dropdown_extra_level2
23
 
24
- def dropdown_collision():
25
  label = "Collision with a means of transport"
26
- add_data_tmp("wounded_dead", "circumstance", label.lower())
27
- return create_dropdown_level1(label)
28
 
29
- def dropdown_deliberate_destruction():
30
  label = "Destruction / Deliberatly removed"
31
- add_data_tmp("wounded_dead", "circumstance", label.lower())
32
- return create_dropdown_level1(label)
33
 
34
- def dropdown_indirect_destruction():
35
  label = "Indirect destruction"
36
- add_data_tmp("wounded_dead", "circumstance", label.lower())
37
- return create_dropdown_level1(label)
38
 
39
- def dropdown_natural_cause():
40
  label = "Natural cause"
41
- add_data_tmp("wounded_dead", "circumstance", label.lower())
42
- return create_dropdown_level1(label)
43
 
44
 
45
  #--------------------------------------------------------- LEVEL 2 DROPDOWNS
@@ -70,15 +70,15 @@ def get_options(value):
70
  return options_label, options_dropdown, open_field, extras, extras_label
71
 
72
 
73
- def on_select(evt: gr.SelectData): # SelectData is a subclass of EventData
74
  options_label, options_dropdown, open_field, extras, extras_label = get_options(evt.value)
75
- add_data_tmp("wounded_dead",
76
  "circumstance_type",
77
  {"type": (evt.value).lower(),
78
  "option_dropdown_label" : options_label.lower() if options_label is not None else 'NA',
79
  "open_field_label" : open_field.lower() if open_field is not None else 'NA',
80
  "extra_label": extras_label.lower() if extras_label is not None else 'NA'
81
- })
82
  if options_dropdown is not None:
83
  dropdown_level2 = gr.Dropdown(choices=options_dropdown, label=evt.value, interactive=True, visible=True)
84
  else:
@@ -93,20 +93,23 @@ def on_select(evt: gr.SelectData): # SelectData is a subclass of EventData
93
  dropdown_extra_level2 = gr.Dropdown(choices=extras, label=extras_label, interactive=True, visible=True)
94
  else:
95
  dropdown_extra_level2 = gr.Dropdown(choices=[], visible=False)
96
- return dropdown_level2, openfield_level2, dropdown_extra_level2
97
 
98
- def on_select_dropdown_level2(evt: gr.SelectData):
99
- add_data_tmp("wounded_dead",
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())
 
 
14
  dropdown_extra_level2 = gr.Dropdown(choices=[], visible=False)
15
  return dropdown_level2, openfield_level2, dropdown_extra_level2
16
 
17
+ def create_dropdown_level1(label, individual):
18
  dropdown_config = get_custom_config_dropdowns("config_dropdown_circumstances.json")
19
  options = retrieve_config_options(label, dropdown_config)
20
  dropdown = gr.Dropdown(choices=options, label=label, interactive=True, visible=True)
21
  dropdown_level2, openfield_level2, dropdown_extra_level2 = reinitialise_level2()
22
+ return dropdown, dropdown_level2, openfield_level2, dropdown_extra_level2, individual
23
 
24
+ def dropdown_collision(individual):
25
  label = "Collision with a means of transport"
26
+ individual = add_data_tmp("wounded_dead", "circumstance", label.lower(), individual)
27
+ return create_dropdown_level1(label, individual)
28
 
29
+ def dropdown_deliberate_destruction(individual):
30
  label = "Destruction / Deliberatly removed"
31
+ individual = add_data_tmp("wounded_dead", "circumstance", label.lower(), individual)
32
+ return create_dropdown_level1(label, individual)
33
 
34
+ def dropdown_indirect_destruction(individual):
35
  label = "Indirect destruction"
36
+ individual = add_data_tmp("wounded_dead", "circumstance", label.lower(), individual)
37
+ return create_dropdown_level1(label, individual)
38
 
39
+ def dropdown_natural_cause(individual):
40
  label = "Natural cause"
41
+ individual = add_data_tmp("wounded_dead", "circumstance", label.lower(), individual)
42
+ return create_dropdown_level1(label, individual)
43
 
44
 
45
  #--------------------------------------------------------- LEVEL 2 DROPDOWNS
 
70
  return options_label, options_dropdown, open_field, extras, extras_label
71
 
72
 
73
+ def on_select(evt: gr.SelectData, individual): # SelectData is a subclass of EventData
74
  options_label, options_dropdown, open_field, extras, extras_label = get_options(evt.value)
75
+ individual = add_data_tmp("wounded_dead",
76
  "circumstance_type",
77
  {"type": (evt.value).lower(),
78
  "option_dropdown_label" : options_label.lower() if options_label is not None else 'NA',
79
  "open_field_label" : open_field.lower() if open_field is not None else 'NA',
80
  "extra_label": extras_label.lower() if extras_label is not None else 'NA'
81
+ }, individual)
82
  if options_dropdown is not None:
83
  dropdown_level2 = gr.Dropdown(choices=options_dropdown, label=evt.value, interactive=True, visible=True)
84
  else:
 
93
  dropdown_extra_level2 = gr.Dropdown(choices=extras, label=extras_label, interactive=True, visible=True)
94
  else:
95
  dropdown_extra_level2 = gr.Dropdown(choices=[], visible=False)
96
+ return dropdown_level2, openfield_level2, dropdown_extra_level2, individual
97
 
98
+ def on_select_dropdown_level2(evt: gr.SelectData, individual):
99
+ individual = add_data_tmp("wounded_dead",
100
  "circumstance_option_dropdown",
101
+ evt.value.lower(), individual)
102
+ return individual
103
 
104
+ def on_select_dropdown_extra_level2(evt: gr.SelectData, individual):
105
+ individual = add_data_tmp("wounded_dead",
106
  "circumstance_extra",
107
+ evt.value.lower(), individual)
108
+ return individual
109
 
110
+ def on_change_openfield_level2(openfield_level2_dead, individual):
111
  print("Saving open field")
112
+ individual = add_data_tmp("wounded_dead",
113
  "circumstance_open_field",
114
+ str(openfield_level2_dead).lower(), individual)
115
+ return individual
app/dead.py CHANGED
@@ -5,10 +5,10 @@ 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
 
8
- def show_section_dead(visible):
9
  if visible==True:
10
- add_data_to_individual("wounded_state", "No")
11
- add_data_to_individual("dead_state", "Yes")
12
 
13
  with gr.Column(visible=visible, elem_id="dead") as section_dead:
14
  gr.Markdown("# Dead Animal")
@@ -32,7 +32,7 @@ def show_section_dead(visible):
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, \
 
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
 
8
+ def show_section_dead(visible, individual):
9
  if visible==True:
10
+ individual = add_data_to_individual("wounded_state", "No", individual)
11
+ individual = add_data_to_individual("dead_state", "Yes", individual)
12
 
13
  with gr.Column(visible=visible, elem_id="dead") as section_dead:
14
  gr.Markdown("# Dead Animal")
 
32
  fe_name_recipient, fe_collection_ref = create_followup_open(visible, "dead")
33
 
34
 
35
+ return section_dead, individual, 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, \
app/display.py CHANGED
@@ -11,15 +11,16 @@ 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
 
11
  HEADERS = ["Identifier", "Location", "Wounded", "Dead"]
12
 
13
 
14
+ def save_display_individual(gallery, df, error_box, data):
15
+ #print(data)
16
+ individual, error_box, data = validate_save_individual(data, error_box)
17
  if individual:
18
  all_animals = get_json_all_individuals()
19
  gallery_animals = process_animals_for_gallery(all_animals)
20
  gallery = make_gallery(gallery_animals)
21
  df_animals = process_animals_for_df(all_animals)
22
  df = make_df(df_animals)
23
+ return gallery, df, error_box, data
24
 
25
  # ----------------------------------
26
  # GALLERY
app/follow_up/followup_events.py CHANGED
@@ -39,8 +39,9 @@ def create_fe_answer_dropdown(followup_config, visible, elem_id):
39
  visible=visible, elem_id=elem_id, interactive=True)
40
  return fe_answer_dropdown
41
 
42
- def save_fe(value, key):
43
- add_data_tmp("wounded_dead", "followup " + key.lower(), value.lower())
 
44
 
45
 
46
 
 
39
  visible=visible, elem_id=elem_id, interactive=True)
40
  return fe_answer_dropdown
41
 
42
+ def save_fe(value, key, individual):
43
+ individual = add_data_tmp("wounded_dead", "followup " + key.lower(), value.lower())
44
+ return individual
45
 
46
 
47
 
app/geolocalisation/js_geolocation.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # JavaScript code to get location and update hidden_input
2
+ js_geocode = """
3
+ function() {
4
+ var textbox = document.querySelector('#textbox_id textarea');
5
+ console.log(textbox)
6
+ if (navigator.geolocation) {
7
+ navigator.geolocation.getCurrentPosition(
8
+ function(position) {
9
+ var data = {
10
+ 'latitude': position.coords.latitude,
11
+ 'longitude': position.coords.longitude,
12
+ 'accuracy': position.coords.accuracy
13
+ };
14
+ console.log("Geolocation data:", data);
15
+ textbox.value = JSON.stringify(data);
16
+ textbox.dispatchEvent(new Event('input', { bubbles: true }));
17
+ },
18
+ function(error) {
19
+ var data = {'error': error.message};
20
+ console.log("Geolocation error:", data);
21
+ textbox.value = JSON.stringify(data);
22
+ textbox.dispatchEvent(new Event('input', { bubbles: true }));
23
+ }
24
+ );
25
+ } else {
26
+ var data = {'error': 'Geolocation is not supported by this browser.'};
27
+ console.log("Geolocation unsupported:", data);
28
+ textbox.value = JSON.stringify(data);
29
+ textbox.dispatchEvent(new Event('input', { bubbles: true }));
30
+ }
31
+ }
32
+ """
33
+
34
+ def display_location(location_json):
35
+ return location_json
app/geolocalisation/maps.py CHANGED
@@ -15,11 +15,12 @@ def create_geolocalisation_object(lat, long, name):
15
  print("Pydantic Error for Geolocalisation")
16
  return geolocalisation
17
 
18
- def save_geolocalisation_to_json(geolocalisation):
19
  geo_dict = geolocalisation.dict()
20
- add_data_to_individual("geolocalisation", geo_dict)
 
21
 
22
- def get_location(address):
23
  try:
24
  # calling the Nominatim tool
25
  loc = Nominatim(user_agent="GetLoc")
@@ -33,18 +34,18 @@ def get_location(address):
33
 
34
  # Save values
35
  geolocalisation = create_geolocalisation_object(lat, lon, address)
36
- save_geolocalisation_to_json(geolocalisation)
37
 
38
  #display location processing
39
  value = "Latitude = " + str(lat) + "\n" + "Longitude = " + str(lon)
40
  identified_location= gr.Textbox(visible=True, interactive=False,
41
  label="Identified GPS Location",
42
  value=value)
43
- return identified_location
44
 
45
  except:
46
  error = "Please try another less precise location."
47
  identified_location= gr.Textbox(visible=True, interactive=False,
48
  label="Identified GPS Location",
49
  value=error)
50
- return identified_location
 
15
  print("Pydantic Error for Geolocalisation")
16
  return geolocalisation
17
 
18
+ def save_geolocalisation_to_json(geolocalisation, individual):
19
  geo_dict = geolocalisation.dict()
20
+ individual = add_data_to_individual("geolocalisation", geo_dict, individual)
21
+ return individual
22
 
23
+ def get_location(address, individual):
24
  try:
25
  # calling the Nominatim tool
26
  loc = Nominatim(user_agent="GetLoc")
 
34
 
35
  # Save values
36
  geolocalisation = create_geolocalisation_object(lat, lon, address)
37
+ individual = save_geolocalisation_to_json(geolocalisation, individual)
38
 
39
  #display location processing
40
  value = "Latitude = " + str(lat) + "\n" + "Longitude = " + str(lon)
41
  identified_location= gr.Textbox(visible=True, interactive=False,
42
  label="Identified GPS Location",
43
  value=value)
44
+ return identified_location, individual
45
 
46
  except:
47
  error = "Please try another less precise location."
48
  identified_location= gr.Textbox(visible=True, interactive=False,
49
  label="Identified GPS Location",
50
  value=error)
51
+ return identified_location, individual
app/main.py CHANGED
@@ -18,8 +18,13 @@ 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(theme='shivi/calm_seafoam') as demo:
 
 
 
23
  create_json_all_individuals()
24
  # ---------------------------------------------------------
25
  # Intro Text
@@ -47,57 +52,102 @@ with gr.Blocks(theme='shivi/calm_seafoam') as demo:
47
  # ---------------------------------------------------------
48
  # Camera
49
  with gr.Row():
50
- def save_image(camera):
51
- add_data_to_individual("image", camera.tolist())
 
52
 
53
  camera = gr.Image(elem_id="image")
54
- camera.input(save_image, inputs=[camera])
55
  # ---------------------------------------------------------
56
  # Location
57
  #with gr.Row():
58
  with gr.Column(scale=1):
 
 
59
  location = gr.Textbox(visible=True, interactive=True, label="Location of Sighting")
60
  #display location processing
61
  identified_location= gr.Textbox(visible=False, interactive=False,
62
  label="Identified GPS Location")
63
  with gr.Row():
64
  #to submit it
65
- submit_location = gr.Button("Get GPS Coordinates",
66
  visible=True, interactive=True, scale=3)
67
- submit_location.click(get_location, inputs=[location], outputs=[identified_location])
68
  #to clear it
69
  clear_location = gr.ClearButton(components=[location, identified_location],
70
  visible=True, interactive=True, scale=1
71
  )
72
  clear_location.click()
73
 
74
- # TODO: Introduce text_box for Species
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
 
76
- # TODO: Introduce text_box for comments
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
 
78
 
79
  # ---------------------------------------------------------
80
  # ---------------------------------------------------------
81
  # Dead and Wounded Buttons
82
  gr.Markdown("## The State of the Animal", label="Title")
83
- gr.Markdown("Please tell us if the animal was wounded or dead.", label="description")
84
  with gr.Row() as block_form:
85
  with gr.Column(scale=1):
86
- butt_wounded = gr.Button("Wounded", elem_id="wounded")
87
  with gr.Column(scale=1):
88
  butt_dead = gr.Button("Dead", elem_id="dead")
89
 
90
  # ---------------------------------------------------------
91
  # Initiate sections
92
- section_dead, radio_circumstance_dead, radio_physical_dead,\
93
  button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead, \
94
  dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, \
95
  physical_boxes_dead, \
96
  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, \
97
  fe_collection_dropdown_dead, fe_recepient_dropdown_dead, fe_radio_dropdown_dead, fe_answer_dropdown_dead, \
98
  fe_name_recipient_dead, fe_collection_ref_dead \
99
- = show_section_dead(False)
100
- section_wounded, radio_circumstance_wounded, radio_behavior_wounded, radio_physical_wounded, \
 
101
  button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded, \
102
  dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded, \
103
  behavior_checkbox, behavior_text, \
@@ -105,7 +155,7 @@ with gr.Blocks(theme='shivi/calm_seafoam') as demo:
105
  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, \
106
  fe_collection_dropdown_wounded, fe_recepient_dropdown_wounded, fe_radio_dropdown_wounded, fe_answer_dropdown_wounded, \
107
  fe_name_recipient_wounded, fe_collection_ref_wounded \
108
- = show_section_wounded(False)
109
 
110
  # ---------------------------------------------------------
111
  # ---------------------------------------------------------
@@ -114,8 +164,9 @@ with gr.Blocks(theme='shivi/calm_seafoam') as demo:
114
  partial_show_section_dead = partial(show_section_dead, True)
115
  partial_hide_section_wounded = partial(show_section_wounded, False)
116
  butt_dead.click(partial_show_section_dead,
117
- inputs=None,
118
  outputs=[section_dead,
 
119
  radio_circumstance_dead, radio_physical_dead,
120
  button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead,
121
  dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, \
@@ -124,9 +175,11 @@ with gr.Blocks(theme='shivi/calm_seafoam') as demo:
124
  fe_collection_dropdown_dead, fe_recepient_dropdown_dead, fe_radio_dropdown_dead, fe_answer_dropdown_dead, \
125
  fe_name_recipient_dead, fe_collection_ref_dead \
126
  ])
 
127
  butt_dead.click(partial_hide_section_wounded,
128
- inputs=None,
129
  outputs=[section_wounded,
 
130
  radio_circumstance_wounded, radio_behavior_wounded, radio_physical_wounded,
131
  button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded,
132
  dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded,
@@ -143,26 +196,32 @@ with gr.Blocks(theme='shivi/calm_seafoam') as demo:
143
  partial_hide_section_dead = partial(show_section_dead, False)
144
 
145
  butt_wounded.click(partial_show_section_wounded,
146
- inputs=None,
147
  outputs=[section_wounded,
148
- radio_circumstance_wounded, radio_behavior_wounded, radio_physical_wounded,
149
- button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded,
150
- dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded,
151
- behavior_checkbox, behavior_text,
152
- physical_boxes_wounded, \
153
- 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, \
154
- fe_collection_dropdown_wounded, fe_recepient_dropdown_wounded, fe_radio_dropdown_wounded, fe_answer_dropdown_wounded, \
155
- fe_name_recipient_wounded, fe_collection_ref_wounded \
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
  ])
157
- butt_wounded.click(partial_hide_section_dead, inputs=None, outputs=[section_dead,
158
- radio_circumstance_dead, radio_physical_dead,
159
- button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead,
160
- dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, \
161
- physical_boxes_dead, \
162
- 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, \
163
- fe_collection_dropdown_dead, fe_recepient_dropdown_dead, fe_radio_dropdown_dead, fe_answer_dropdown_dead, \
164
- fe_name_recipient_dead, fe_collection_ref_dead \
165
- ])
166
  # ---------------------------------------------------------
167
  # ---------------------------------------------------------
168
  # ---------------------------------------------------------
@@ -171,27 +230,28 @@ with gr.Blocks(theme='shivi/calm_seafoam') as demo:
171
  # ---------------------------------------------------------
172
  # Radio Circumstance Dead
173
  radio_circumstance_dead.change(fn=show_circumstances,
174
- inputs=[radio_circumstance_dead],
175
  outputs=[button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead,
176
- dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead]
177
  )
178
 
179
  # Dropdowns Dead
180
- button_collision_dead.click(dropdown_collision,
181
- outputs=[dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead])
182
- button_deliberate_destruction_dead.click(dropdown_deliberate_destruction, outputs=[dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead])
183
- button_indirect_destruction_dead.click(dropdown_indirect_destruction, outputs=[dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead])
184
- button_natural_cause_dead.click(dropdown_natural_cause, outputs=[dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead])
 
185
 
186
- dropdown_dead.select(on_select, None, [dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead])
187
- dropdown_level2_dead.select(on_select_dropdown_level2)
188
- openfield_level2_dead.change(on_change_openfield_level2, inputs=[openfield_level2_dead])
189
- dropdown_extra_level2_dead.select(on_select_dropdown_extra_level2)
190
  # ---------------------------------------------------------
191
  # Radio Physical Dead
192
  radio_physical_dead.change(fn=show_physical,
193
- inputs=[radio_physical_dead, gr.Text("dead", visible=False)],
194
- outputs=[physical_boxes_dead])
195
 
196
  # Checkbox Physical Dead
197
  physical_boxes_dead.select(find_bounding_box,
@@ -202,11 +262,11 @@ with gr.Blocks(theme='shivi/calm_seafoam') as demo:
202
  checkbox_head_dead, text_head_dead,
203
  checkbox_legs_dead, text_legs_dead
204
  ])
205
- checkbox_beak_dead.select(on_select_body_part, inputs=[checkbox_beak_dead, gr.Text("beak", visible=False)])
206
- checkbox_body_dead.select(on_select_body_part, inputs=[checkbox_body_dead, gr.Text("body", visible=False)])
207
- checkbox_feathers_dead.select(on_select_body_part, inputs=[checkbox_feathers_dead, gr.Text("feathers", visible=False)])
208
- checkbox_head_dead.select(on_select_body_part, inputs=[checkbox_head_dead, gr.Text("head", visible=False)])
209
- checkbox_legs_dead.select(on_select_body_part, inputs=[checkbox_legs_dead, gr.Text("legs", visible=False)])
210
  # ---------------------------------------------------------
211
  # ---------------------------------------------------------
212
  # ---------------------------------------------------------
@@ -215,67 +275,69 @@ with gr.Blocks(theme='shivi/calm_seafoam') as demo:
215
  # ---------------------------------------------------------
216
  # Radio Circumstance Wounded
217
  radio_circumstance_wounded.change(fn=show_circumstances,
218
- inputs=[radio_circumstance_wounded],
219
  outputs=[button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded,
220
- dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded]
221
  )
222
 
223
  # Dropdowns Circumstance Wounded
224
- button_collision_wounded.click(dropdown_collision,
225
- outputs=[dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded])
226
- button_deliberate_destruction_wounded.click(dropdown_deliberate_destruction, outputs=[dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded])
227
- button_indirect_destruction_wounded.click(dropdown_indirect_destruction, outputs=[dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded])
228
- button_natural_cause_wounded.click(dropdown_natural_cause, outputs=[dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded])
 
229
 
230
- dropdown_wounded.select(on_select, None, [dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded])
231
- dropdown_level2_wounded.select(on_select_dropdown_level2)
232
- openfield_level2_wounded.change(on_change_openfield_level2, inputs=[openfield_level2_wounded])
233
- dropdown_extra_level2_wounded.select(on_select_dropdown_extra_level2)
234
  # ---------------------------------------------------------
235
  # Radio Behavior Wounded
236
  radio_behavior_wounded.change(fn=show_behavior,
237
- inputs=[radio_behavior_wounded, gr.Text("wounded", visible=False)],
238
- outputs=[behavior_checkbox, behavior_text])
239
  behavior_checkbox.select(on_select_behavior,
240
- inputs=[behavior_checkbox])
 
241
  # ---------------------------------------------------------
242
  # Radio Physical Wounded
243
  radio_physical_wounded.change(fn=show_physical,
244
- inputs=[radio_physical_wounded, gr.Text("wounded", visible=False)],
245
- outputs=[physical_boxes_wounded])
246
 
247
  # Checkbox Physical Wounded
248
  physical_boxes_wounded.select(find_bounding_box,
249
- inputs=[physical_boxes_wounded, gr.Textbox(value="wounded", visible=False)],
250
  outputs=[checkbox_beak_wounded, text_beak_wounded,
251
  checkbox_body_wounded, text_body_wounded,
252
  checkbox_feathers_wounded, text_feathers_wounded,
253
  checkbox_head_wounded, text_head_wounded,
254
  checkbox_legs_wounded, text_legs_wounded
255
  ])
256
- checkbox_beak_wounded.select(on_select_body_part, inputs=[checkbox_beak_wounded, gr.Text("beak", visible=False)])
257
- checkbox_body_wounded.select(on_select_body_part, inputs=[checkbox_body_wounded, gr.Text("body", visible=False)])
258
- checkbox_feathers_wounded.select(on_select_body_part, inputs=[checkbox_feathers_wounded, gr.Text("feathers", visible=False)])
259
- checkbox_head_wounded.select(on_select_body_part, inputs=[checkbox_head_wounded, gr.Text("head", visible=False)])
260
- checkbox_legs_wounded.select(on_select_body_part, inputs=[checkbox_legs_wounded, gr.Text("legs", visible=False)])
261
 
262
  # ---------------------------------------------------------
263
  # Follow Up Events Wounded
264
- fe_collection_dropdown_wounded.select(save_fe, inputs=[fe_collection_dropdown_wounded, gr.Textbox("animal collected", visible=False)])
265
- fe_recepient_dropdown_wounded.select(save_fe, inputs=[fe_recepient_dropdown_wounded, gr.Textbox("recipient", visible=False)])
266
- fe_radio_dropdown_wounded.select(save_fe, inputs=[fe_radio_dropdown_wounded, gr.Textbox("radiography", visible=False)])
267
- fe_answer_dropdown_wounded.select(save_fe, inputs=[fe_answer_dropdown_wounded, gr.Textbox("given answer", visible=False)])
268
- fe_name_recipient_wounded.input(save_fe, inputs=[fe_name_recipient_wounded, gr.Textbox("recipient name", visible=False)])
269
- fe_collection_ref_wounded.input(save_fe, inputs=[fe_collection_ref_wounded, gr.Textbox("collection reference", visible=False)])
270
 
271
  # ---------------------------------------------------------
272
  # Follow Up Events Dead
273
- fe_collection_dropdown_dead.select(save_fe, inputs=[fe_collection_dropdown_dead, gr.Textbox("animal collected", visible=False)])
274
- fe_recepient_dropdown_dead.select(save_fe, inputs=[fe_recepient_dropdown_dead, gr.Textbox("recipient", visible=False)])
275
- fe_radio_dropdown_dead.select(save_fe, inputs=[fe_radio_dropdown_dead, gr.Textbox("radiography", visible=False)])
276
- fe_answer_dropdown_dead.select(save_fe, inputs=[fe_answer_dropdown_dead, gr.Textbox("given answer", visible=False)])
277
- fe_name_recipient_dead.input(save_fe, inputs=[fe_name_recipient_dead, gr.Textbox("recipient name", visible=False)])
278
- fe_collection_ref_dead.input(save_fe, inputs=[fe_collection_ref_dead, gr.Textbox("collection reference", visible=False)])
279
 
280
  # ---------------------------------------------------------
281
  # Error Box
@@ -324,8 +386,8 @@ with gr.Blocks(theme='shivi/calm_seafoam') as demo:
324
  button_clear.click(reset_json)
325
 
326
  button_df.click(save_display_individual,
327
- inputs=[gallery, df, error_box],
328
- outputs=[gallery, df, error_box]
329
  )
330
  button_close.click(lambda: Modal(visible=False), None, modal)
331
 
 
18
  from styling.style import *
19
  from styling.theme import css
20
 
21
+ from geolocalisation.js_geolocation import js_geocode, display_location
22
+
23
  # with gr.Blocks(theme=theme, css=css) as demo:
24
  with gr.Blocks(theme='shivi/calm_seafoam') as demo:
25
+ individual = gr.State({})
26
+
27
+ #with gr.Blocks() as demo:
28
  create_json_all_individuals()
29
  # ---------------------------------------------------------
30
  # Intro Text
 
52
  # ---------------------------------------------------------
53
  # Camera
54
  with gr.Row():
55
+ def save_image(camera, individual):
56
+ individual = add_data_to_individual("image", camera.tolist(), individual)
57
+ return individual
58
 
59
  camera = gr.Image(elem_id="image")
60
+ camera.input(save_image, inputs=[camera, individual], outputs=[individual])
61
  # ---------------------------------------------------------
62
  # Location
63
  #with gr.Row():
64
  with gr.Column(scale=1):
65
+ gr.Markdown("### Location")
66
+ gr.Markdown("#### Location (Using address)")
67
  location = gr.Textbox(visible=True, interactive=True, label="Location of Sighting")
68
  #display location processing
69
  identified_location= gr.Textbox(visible=False, interactive=False,
70
  label="Identified GPS Location")
71
  with gr.Row():
72
  #to submit it
73
+ submit_location = gr.Button("Get Coordinates using address",
74
  visible=True, interactive=True, scale=3)
75
+ submit_location.click(get_location, inputs=[location, individual], outputs=[identified_location, individual])
76
  #to clear it
77
  clear_location = gr.ClearButton(components=[location, identified_location],
78
  visible=True, interactive=True, scale=1
79
  )
80
  clear_location.click()
81
 
82
+ # Geolocation
83
+ gr.Markdown("#### Location (Using GPS)")
84
+ location_data = gr.JSON(label="Identified GPS Location")
85
+ hidden_input = gr.Textbox(visible=False, elem_id="textbox_id")
86
+ btn_gpslocation = gr.Button("Get Coordinates using GPS (Permission required)")
87
+ btn_gpslocation.click(None, [], [], js=js_geocode)
88
+ hidden_input.change(display_location, inputs=hidden_input, outputs=location_data)
89
+
90
+
91
+ # Introducing text_box for Species
92
+ gr.Markdown("### General details")
93
+ with gr.Row():
94
+ specie = gr.Textbox(
95
+ label="Species (if known)",
96
+ placeholder="e.g. European Robin, Common Blackbird",
97
+ info="Enter the species name if you can identify it. If unsure, provide your best guess or general description (e.g. 'small brown bird')",
98
+ visible=True,
99
+ interactive=True
100
+ )
101
 
102
+ # Number of individuals
103
+ with gr.Row():
104
+ num_individuals = gr.Number(
105
+ label="Number of Individuals",
106
+ value=1, # Default value
107
+ minimum=1,
108
+ precision=0, # Only whole numbers
109
+ info="Enter the number of animals observed",
110
+ #placeholder="Enter number...",
111
+ visible=True,
112
+ interactive=True
113
+ )
114
+
115
+ # Introducing text_box for comments
116
+ with gr.Row():
117
+ comments = gr.TextArea(
118
+ label="Additional Comments",
119
+ placeholder="Enter any additional observations or notes about the sighting...",
120
+ info="Optional: Add any relevant details about the animal(s) or circumstances",
121
+ lines=3,
122
+ max_lines=5,
123
+ visible=True,
124
+ interactive=True
125
+ )
126
 
127
 
128
  # ---------------------------------------------------------
129
  # ---------------------------------------------------------
130
  # Dead and Wounded Buttons
131
  gr.Markdown("## The State of the Animal", label="Title")
132
+ gr.Markdown("Please tell us if the animal was wounded / sick or dead.", label="description")
133
  with gr.Row() as block_form:
134
  with gr.Column(scale=1):
135
+ butt_wounded = gr.Button("Wounded / Sick", elem_id="wounded")
136
  with gr.Column(scale=1):
137
  butt_dead = gr.Button("Dead", elem_id="dead")
138
 
139
  # ---------------------------------------------------------
140
  # Initiate sections
141
+ section_dead, individual, radio_circumstance_dead, radio_physical_dead,\
142
  button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead, \
143
  dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, \
144
  physical_boxes_dead, \
145
  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, \
146
  fe_collection_dropdown_dead, fe_recepient_dropdown_dead, fe_radio_dropdown_dead, fe_answer_dropdown_dead, \
147
  fe_name_recipient_dead, fe_collection_ref_dead \
148
+ = show_section_dead(False, individual)
149
+
150
+ section_wounded, individual, radio_circumstance_wounded, radio_behavior_wounded, radio_physical_wounded, \
151
  button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded, \
152
  dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded, \
153
  behavior_checkbox, behavior_text, \
 
155
  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, \
156
  fe_collection_dropdown_wounded, fe_recepient_dropdown_wounded, fe_radio_dropdown_wounded, fe_answer_dropdown_wounded, \
157
  fe_name_recipient_wounded, fe_collection_ref_wounded \
158
+ = show_section_wounded(False, individual)
159
 
160
  # ---------------------------------------------------------
161
  # ---------------------------------------------------------
 
164
  partial_show_section_dead = partial(show_section_dead, True)
165
  partial_hide_section_wounded = partial(show_section_wounded, False)
166
  butt_dead.click(partial_show_section_dead,
167
+ inputs=[individual],
168
  outputs=[section_dead,
169
+ individual,
170
  radio_circumstance_dead, radio_physical_dead,
171
  button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead,
172
  dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, \
 
175
  fe_collection_dropdown_dead, fe_recepient_dropdown_dead, fe_radio_dropdown_dead, fe_answer_dropdown_dead, \
176
  fe_name_recipient_dead, fe_collection_ref_dead \
177
  ])
178
+
179
  butt_dead.click(partial_hide_section_wounded,
180
+ inputs=[individual],
181
  outputs=[section_wounded,
182
+ individual,
183
  radio_circumstance_wounded, radio_behavior_wounded, radio_physical_wounded,
184
  button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded,
185
  dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded,
 
196
  partial_hide_section_dead = partial(show_section_dead, False)
197
 
198
  butt_wounded.click(partial_show_section_wounded,
199
+ inputs=[individual],
200
  outputs=[section_wounded,
201
+ individual,
202
+ radio_circumstance_wounded, radio_behavior_wounded, radio_physical_wounded,
203
+ button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded,
204
+ dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded,
205
+ behavior_checkbox, behavior_text,
206
+ physical_boxes_wounded, \
207
+ 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, \
208
+ fe_collection_dropdown_wounded, fe_recepient_dropdown_wounded, fe_radio_dropdown_wounded, fe_answer_dropdown_wounded, \
209
+ fe_name_recipient_wounded, fe_collection_ref_wounded \
210
+ ])
211
+
212
+ butt_wounded.click(partial_hide_section_dead,
213
+ inputs=[individual],
214
+ outputs=[section_dead,
215
+ individual,
216
+ radio_circumstance_dead, radio_physical_dead,
217
+ button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead,
218
+ dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, \
219
+ physical_boxes_dead, \
220
+ 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, \
221
+ fe_collection_dropdown_dead, fe_recepient_dropdown_dead, fe_radio_dropdown_dead, fe_answer_dropdown_dead, \
222
+ fe_name_recipient_dead, fe_collection_ref_dead \
223
  ])
224
+
 
 
 
 
 
 
 
 
225
  # ---------------------------------------------------------
226
  # ---------------------------------------------------------
227
  # ---------------------------------------------------------
 
230
  # ---------------------------------------------------------
231
  # Radio Circumstance Dead
232
  radio_circumstance_dead.change(fn=show_circumstances,
233
+ inputs=[radio_circumstance_dead, individual],
234
  outputs=[button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead,
235
+ dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, individual]
236
  )
237
 
238
  # Dropdowns Dead
239
+ button_collision_dead.click(dropdown_collision,
240
+ inputs=[individual],
241
+ outputs=[dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, individual])
242
+ button_deliberate_destruction_dead.click(dropdown_deliberate_destruction, inputs=[individual], outputs=[dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, individual])
243
+ button_indirect_destruction_dead.click(dropdown_indirect_destruction, inputs=[individual], outputs=[dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, individual])
244
+ button_natural_cause_dead.click(dropdown_natural_cause, inputs=[individual], outputs=[dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, individual])
245
 
246
+ dropdown_dead.select(on_select, inputs=[individual], outputs=[dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, individual])
247
+ dropdown_level2_dead.select(on_select_dropdown_level2, inputs=[individual], outputs=[individual] )
248
+ openfield_level2_dead.change(on_change_openfield_level2, inputs=[openfield_level2_dead, individual], outputs=[individual])
249
+ dropdown_extra_level2_dead.select(on_select_dropdown_extra_level2, inputs=[individual], outputs=[individual])
250
  # ---------------------------------------------------------
251
  # Radio Physical Dead
252
  radio_physical_dead.change(fn=show_physical,
253
+ inputs=[radio_physical_dead, gr.Text("dead", visible=False), individual],
254
+ outputs=[physical_boxes_dead, individual])
255
 
256
  # Checkbox Physical Dead
257
  physical_boxes_dead.select(find_bounding_box,
 
262
  checkbox_head_dead, text_head_dead,
263
  checkbox_legs_dead, text_legs_dead
264
  ])
265
+ checkbox_beak_dead.select(on_select_body_part, inputs=[checkbox_beak_dead, gr.Text("beak", visible=False), individual], outputs=[individual])
266
+ checkbox_body_dead.select(on_select_body_part, inputs=[checkbox_body_dead, gr.Text("body", visible=False), individual], outputs=[individual])
267
+ checkbox_feathers_dead.select(on_select_body_part, inputs=[checkbox_feathers_dead, gr.Text("feathers", visible=False), individual], outputs=[individual])
268
+ checkbox_head_dead.select(on_select_body_part, inputs=[checkbox_head_dead, gr.Text("head", visible=False), individual], outputs=[individual])
269
+ checkbox_legs_dead.select(on_select_body_part, inputs=[checkbox_legs_dead, gr.Text("legs", visible=False), individual], outputs=[individual])
270
  # ---------------------------------------------------------
271
  # ---------------------------------------------------------
272
  # ---------------------------------------------------------
 
275
  # ---------------------------------------------------------
276
  # Radio Circumstance Wounded
277
  radio_circumstance_wounded.change(fn=show_circumstances,
278
+ inputs=[radio_circumstance_wounded, individual],
279
  outputs=[button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded,
280
+ dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded, individual]
281
  )
282
 
283
  # Dropdowns Circumstance Wounded
284
+ button_collision_wounded.click(dropdown_collision,
285
+ inputs=[individual],
286
+ outputs=[dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded, individual])
287
+ button_deliberate_destruction_wounded.click(dropdown_deliberate_destruction, inputs=[individual], outputs=[dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded, individual])
288
+ button_indirect_destruction_wounded.click(dropdown_indirect_destruction, inputs=[individual], outputs=[dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded, individual])
289
+ button_natural_cause_wounded.click(dropdown_natural_cause, inputs=[individual], outputs=[dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded, individual])
290
 
291
+ dropdown_wounded.select(on_select, inputs=[individual], outputs=[dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded, individual])
292
+ dropdown_level2_wounded.select(on_select_dropdown_level2, inputs=[individual], outputs=[individual])
293
+ openfield_level2_wounded.change(on_change_openfield_level2, inputs=[openfield_level2_wounded, individual])
294
+ dropdown_extra_level2_wounded.select(on_select_dropdown_extra_level2, inputs=[individual], outputs=[individual])
295
  # ---------------------------------------------------------
296
  # Radio Behavior Wounded
297
  radio_behavior_wounded.change(fn=show_behavior,
298
+ inputs=[radio_behavior_wounded, gr.Text("wounded / sick", visible=False), individual],
299
+ outputs=[behavior_checkbox, behavior_text, individual])
300
  behavior_checkbox.select(on_select_behavior,
301
+ inputs=[behavior_checkbox, individual],
302
+ outputs=[individual])
303
  # ---------------------------------------------------------
304
  # Radio Physical Wounded
305
  radio_physical_wounded.change(fn=show_physical,
306
+ inputs=[radio_physical_wounded, gr.Text("wounded / sick", visible=False), individual],
307
+ outputs=[physical_boxes_wounded, individual])
308
 
309
  # Checkbox Physical Wounded
310
  physical_boxes_wounded.select(find_bounding_box,
311
+ inputs=[physical_boxes_wounded, gr.Textbox(value="wounded / sick", visible=False)],
312
  outputs=[checkbox_beak_wounded, text_beak_wounded,
313
  checkbox_body_wounded, text_body_wounded,
314
  checkbox_feathers_wounded, text_feathers_wounded,
315
  checkbox_head_wounded, text_head_wounded,
316
  checkbox_legs_wounded, text_legs_wounded
317
  ])
318
+ checkbox_beak_wounded.select(on_select_body_part, inputs=[checkbox_beak_wounded, gr.Text("beak", visible=False), individual], outputs=[individual])
319
+ checkbox_body_wounded.select(on_select_body_part, inputs=[checkbox_body_wounded, gr.Text("body", visible=False), individual], outputs=[individual])
320
+ checkbox_feathers_wounded.select(on_select_body_part, inputs=[checkbox_feathers_wounded, gr.Text("feathers", visible=False), individual], outputs=[individual])
321
+ checkbox_head_wounded.select(on_select_body_part, inputs=[checkbox_head_wounded, gr.Text("head", visible=False), individual], outputs=[individual])
322
+ checkbox_legs_wounded.select(on_select_body_part, inputs=[checkbox_legs_wounded, gr.Text("legs", visible=False), individual], outputs=[individual])
323
 
324
  # ---------------------------------------------------------
325
  # Follow Up Events Wounded
326
+ fe_collection_dropdown_wounded.select(save_fe, inputs=[fe_collection_dropdown_wounded, gr.Textbox("animal collected", visible=False), individual], outputs=[individual])
327
+ fe_recepient_dropdown_wounded.select(save_fe, inputs=[fe_recepient_dropdown_wounded, gr.Textbox("recipient", visible=False), individual],outputs=[individual])
328
+ fe_radio_dropdown_wounded.select(save_fe, inputs=[fe_radio_dropdown_wounded, gr.Textbox("radiography", visible=False), individual],outputs=[individual])
329
+ fe_answer_dropdown_wounded.select(save_fe, inputs=[fe_answer_dropdown_wounded, gr.Textbox("given answer", visible=False), individual],outputs=[individual])
330
+ fe_name_recipient_wounded.input(save_fe, inputs=[fe_name_recipient_wounded, gr.Textbox("recipient name", visible=False), individual],outputs=[individual])
331
+ fe_collection_ref_wounded.input(save_fe, inputs=[fe_collection_ref_wounded, gr.Textbox("collection reference", visible=False), individual],outputs=[individual])
332
 
333
  # ---------------------------------------------------------
334
  # Follow Up Events Dead
335
+ fe_collection_dropdown_dead.select(save_fe, inputs=[fe_collection_dropdown_dead, gr.Textbox("animal collected", visible=False), individual],outputs=[individual])
336
+ fe_recepient_dropdown_dead.select(save_fe, inputs=[fe_recepient_dropdown_dead, gr.Textbox("recipient", visible=False), individual],outputs=[individual])
337
+ fe_radio_dropdown_dead.select(save_fe, inputs=[fe_radio_dropdown_dead, gr.Textbox("radiography", visible=False), individual],outputs=[individual])
338
+ fe_answer_dropdown_dead.select(save_fe, inputs=[fe_answer_dropdown_dead, gr.Textbox("given answer", visible=False), individual],outputs=[individual])
339
+ fe_name_recipient_dead.input(save_fe, inputs=[fe_name_recipient_dead, gr.Textbox("recipient name", visible=False), individual],outputs=[individual])
340
+ fe_collection_ref_dead.input(save_fe, inputs=[fe_collection_ref_dead, gr.Textbox("collection reference", visible=False), individual], outputs=[individual])
341
 
342
  # ---------------------------------------------------------
343
  # Error Box
 
386
  button_clear.click(reset_json)
387
 
388
  button_df.click(save_display_individual,
389
+ inputs=[gallery, df, error_box, individual],
390
+ outputs=[gallery, df, error_box, individual]
391
  )
392
  button_close.click(lambda: Modal(visible=False), None, modal)
393
 
app/physical/physical_checkbox.py CHANGED
@@ -71,10 +71,11 @@ def process_body_parts(section, matched_box):
71
 
72
  #---------------------------------------------------------
73
 
74
- def on_select_body_part(body_part_checkbox, body_part):
75
- add_data_tmp("wounded_dead", "physical_type_"+body_part.lower(), body_part.lower())
76
  body_part_checkbox = [body_part_check.lower() for body_part_check in body_part_checkbox]
77
- add_data_tmp("wounded_dead", "physical_anomaly_"+body_part.lower(), body_part_checkbox)
 
78
 
79
  #---------------------------------------------------------
80
 
 
71
 
72
  #---------------------------------------------------------
73
 
74
+ def on_select_body_part(body_part_checkbox, body_part, individual):
75
+ individual = add_data_tmp("wounded_dead", "physical_type_"+body_part.lower(), body_part.lower(), individual)
76
  body_part_checkbox = [body_part_check.lower() for body_part_check in body_part_checkbox]
77
+ individual = add_data_tmp("wounded_dead", "physical_anomaly_"+body_part.lower(), body_part_checkbox, individual)
78
+ return individual
79
 
80
  #---------------------------------------------------------
81
 
app/physical/physical_select_animal.py CHANGED
@@ -37,11 +37,11 @@ def create_bird_anatomy(visible, section: str):
37
  visible=visible)
38
  return img_with_boxes
39
 
40
- def show_physical(choice, section: str):
41
  visible = set_visible(choice)
42
  physical_boxes = create_bird_anatomy(visible, section)
43
- add_data_tmp("wounded_dead", "physical_radio", choice)
44
- return physical_boxes
45
 
46
 
47
 
 
37
  visible=visible)
38
  return img_with_boxes
39
 
40
+ def show_physical(choice, section: str, individual):
41
  visible = set_visible(choice)
42
  physical_boxes = create_bird_anatomy(visible, section)
43
+ individual = add_data_tmp("wounded_dead", "physical_radio", choice, individual)
44
+ return physical_boxes, individual
45
 
46
 
47
 
app/utils/utils_checkbox.py CHANGED
@@ -2,17 +2,17 @@ import gradio as gr
2
 
3
  #---------------------------------------------------------
4
  def create_checkbox(value, section, label_checkbox, visible, options, descriptions):
5
- descriptions_info = "".join([f"\t{option}: {description}\n" for option, description in zip(options, descriptions)])
6
  checkbox = gr.CheckboxGroup(options,
7
  label=label_checkbox + f" {value}:",
8
  visible=visible,
9
  interactive=True,
10
  elem_id=section)
11
- text = gr.Textbox(descriptions_info,
12
  label = "Info",
13
  visible=visible,
14
- interactive=False,
15
- lines=13,
16
- max_lines=15,
17
  elem_id=section)
18
  return checkbox, text
 
2
 
3
  #---------------------------------------------------------
4
  def create_checkbox(value, section, label_checkbox, visible, options, descriptions):
5
+ descriptions_info = "<br><br>".join([f"* **{option}**: {description}" for option, description in zip(options, descriptions)])
6
  checkbox = gr.CheckboxGroup(options,
7
  label=label_checkbox + f" {value}:",
8
  visible=visible,
9
  interactive=True,
10
  elem_id=section)
11
+ text = gr.Markdown(descriptions_info,
12
  label = "Info",
13
  visible=visible,
14
+ #interactive=False,
15
+ #lines=13,
16
+ #max_lines=15,
17
  elem_id=section)
18
  return checkbox, text
app/validation_submission/add_json.py CHANGED
@@ -1,15 +1,19 @@
1
  from validation_submission.create_json import create_json_one_individual, create_tmp
2
  import json
3
 
4
- def add_data_to_individual(key, value):
5
- with open("data/one_individual.json", 'r') as openfile:
6
- one_individual = json.load(openfile)
7
- one_individual[key] = value
8
- create_json_one_individual(one_individual)
 
 
9
 
10
- def add_data_tmp(tmp_name, key, value):
11
- with open(f"app/assets/tmp_json/tmp_{tmp_name}.json", 'r') as openfile:
12
- tmp = json.load(openfile)
13
- tmp[key] = value
14
- create_tmp(tmp_name, tmp)
 
 
15
 
 
1
  from validation_submission.create_json import create_json_one_individual, create_tmp
2
  import json
3
 
4
+ def add_data_to_individual(key, value, individual):
5
+ # with open("data/one_individual.json", 'r') as openfile:
6
+ # one_individual = json.load(openfile)
7
+ # one_individual[key] = value
8
+ # create_json_one_individual(one_individual)
9
+ individual[key] = value
10
+ return individual
11
 
12
+ def add_data_tmp(tmp_name, key, value, individual):
13
+ # with open(f"app/assets/tmp_json/tmp_{tmp_name}.json", 'r') as openfile:
14
+ # tmp = json.load(openfile)
15
+ # tmp[key] = value
16
+ # create_tmp(tmp_name, tmp)
17
+ individual[key] = value
18
+ return individual
19
 
app/validation_submission/processing.py CHANGED
@@ -1,6 +1,7 @@
1
  #### PROCESS FUNCTIONS
2
 
3
  def process_circumstance(data):
 
4
  fields_to_check = ["option_dropdown", "open_field", "extra"]
5
  if data["circumstance_radio"] == "Yes":
6
  for field in fields_to_check:
 
1
  #### PROCESS FUNCTIONS
2
 
3
  def process_circumstance(data):
4
+
5
  fields_to_check = ["option_dropdown", "open_field", "extra"]
6
  if data["circumstance_radio"] == "Yes":
7
  for field in fields_to_check:
app/validation_submission/submission.py CHANGED
@@ -2,11 +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(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()
 
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(data, error_box):
6
+ individual, error_box = validate_individual(data, error_box)
7
  if individual:
8
  save_to_all_individuals(individual.model_dump())
9
+ return individual, error_box, data
10
 
11
  def save_to_all_individuals(one_individual):
12
  all_individuals = get_json_all_individuals()
app/validation_submission/validation.py CHANGED
@@ -10,16 +10,16 @@ from follow_up.class_follow_up import FollowUpEvents
10
  from classes import Report, Wounded, Dead, ImageBase64
11
  from validation_submission.processing import process_circumstance, process_behaviors, process_physical, process_followup
12
 
13
- def get_fields(data_dict, keyword):
14
  extract = {}
15
  for key, val in data_dict.items():
16
  if keyword in key:
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"])
@@ -39,7 +39,7 @@ def validate_individual(error_box):
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)
 
10
  from classes import Report, Wounded, Dead, ImageBase64
11
  from validation_submission.processing import process_circumstance, process_behaviors, process_physical, process_followup
12
 
13
+ def get_fields(data_dict, keyword):
14
  extract = {}
15
  for key, val in data_dict.items():
16
  if keyword in key:
17
  extract[key] = val
18
  return extract
19
 
20
+ def validate_individual(data, error_box):
21
  error_box = reset_error_box(error_box)
22
+ #data = get_json_one_individual() # TODO: This should change
23
  data["identifier"] = str(uuid.uuid4())
24
  if "image" in data.keys():
25
  img = ImageBase64.to_base64(data["image"])
 
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 = data #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)
app/wounded.py CHANGED
@@ -6,13 +6,13 @@ from behavior.behavior_checkbox import create_behavior_checkbox
6
  from follow_up.followup_events import create_followup_dropdowns, create_followup_open
7
  from validation_submission.add_json import add_data_to_individual
8
 
9
- def show_section_wounded(visible):
10
  if visible==True:
11
- add_data_to_individual("wounded_state", "Yes")
12
- add_data_to_individual("dead_state", "No")
13
 
14
  with gr.Column(visible=visible, elem_id="wounded") as wounded_section:
15
- gr.Markdown("# Wounded Animal")
16
 
17
  gr.Markdown("## Do you know what conditions caused this?", label="description")
18
  radio_cause = gr.Radio(["Yes", "No"], value=None, show_label=False, interactive=True)
@@ -40,7 +40,7 @@ def show_section_wounded(visible):
40
 
41
 
42
  # Change variables and names
43
- return wounded_section, radio_cause, radio_behaviour, radio_physical, \
44
  button_collision, button_deliberate_destruction, button_indirect_destruction, button_natural_cause, \
45
  dropdown, dropdown_level2, openfield_level2, dropdown_extra_level2, \
46
  behavior_checkbox, behavior_text, \
 
6
  from follow_up.followup_events import create_followup_dropdowns, create_followup_open
7
  from validation_submission.add_json import add_data_to_individual
8
 
9
+ def show_section_wounded(visible, individual):
10
  if visible==True:
11
+ individual = add_data_to_individual("wounded_state", "Yes", individual)
12
+ individual = add_data_to_individual("dead_state", "No", individual)
13
 
14
  with gr.Column(visible=visible, elem_id="wounded") as wounded_section:
15
+ gr.Markdown("# Wounded / Sick Animal")
16
 
17
  gr.Markdown("## Do you know what conditions caused this?", label="description")
18
  radio_cause = gr.Radio(["Yes", "No"], value=None, show_label=False, interactive=True)
 
40
 
41
 
42
  # Change variables and names
43
+ return wounded_section, individual, radio_cause, radio_behaviour, radio_physical, \
44
  button_collision, button_deliberate_destruction, button_indirect_destruction, button_natural_cause, \
45
  dropdown, dropdown_level2, openfield_level2, dropdown_extra_level2, \
46
  behavior_checkbox, behavior_text, \