Asmit Nayak commited on
Commit
b49a99a
·
1 Parent(s): 9012453

Add detailed results table and CSV download functionality

Browse files
Files changed (1) hide show
  1. app.py +94 -22
app.py CHANGED
@@ -865,11 +865,6 @@ def create_interface():
865
  results_display = gr.HTML(
866
  value="<div style='text-align: center; padding: 40px; color: var(--body-text-color); opacity: 0.7;'>Enter a URL and click analyze to see results here.</div>"
867
  )
868
-
869
- results_dataframe = gr.Dataframe(
870
- label="Detailed Results (Scroll right to see all columns)",
871
- visible=False
872
- )
873
 
874
  with gr.Column(scale=3):
875
  # Screenshot section - only screenshot in right column
@@ -932,7 +927,70 @@ def create_interface():
932
  interactive=False
933
  )
934
 
 
 
 
 
 
 
 
 
 
 
 
 
 
935
  # Event handlers
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
936
  def handle_url_analysis(url, api_key):
937
  """Handle URL analysis with screenshot capture."""
938
  print(f"[CONSOLE] handle_url_analysis called with URL: {url}")
@@ -949,7 +1007,8 @@ def create_interface():
949
  gr.update(visible=True), # Show placeholder initially
950
  gr.update(visible=False), # Hide screenshot initially
951
  "<div style='text-align: center; padding: 20px; color: var(--body-text-color); opacity: 0.7;'>Preparing analysis...</div>", # Clear previous errors
952
- gr.update(visible=False) # Hide dataframe
 
953
  )
954
 
955
  analysis_generator = take_screenshot_and_process(url, api_key)
@@ -976,7 +1035,8 @@ def create_interface():
976
  gr.update(visible=False), # Hide placeholder
977
  gr.update(value=image_path, visible=True, label="📷 Original Screenshot"), # Show original screenshot
978
  "<div style='text-align: center; padding: 20px; color: var(--body-text-color); opacity: 0.7;'>Analysis in progress...</div>", # Clear previous errors
979
- gr.update(visible=False)
 
980
  )
981
  else:
982
  yield (
@@ -984,7 +1044,8 @@ def create_interface():
984
  gr.update(visible=True), # Keep placeholder visible
985
  gr.update(visible=False), # Hide screenshot
986
  "<div style='text-align: center; padding: 20px; color: var(--body-text-color); opacity: 0.7;'>Analysis in progress...</div>", # Clear previous errors
987
- gr.update(visible=False)
 
988
  )
989
  else:
990
  print(f"[CONSOLE] Received final result with {len(dataframe_result)} rows")
@@ -1000,7 +1061,8 @@ def create_interface():
1000
  gr.update(visible=False), # Hide placeholder
1001
  gr.update(value=final_image, visible=True, label="🎯 Annotated Screenshot (Analysis Complete)") if final_image else gr.update(visible=False),
1002
  "<div style='text-align: center; padding: 20px; color: var(--body-text-color); opacity: 0.7;'>Processing results...</div>", # Clear previous errors
1003
- gr.update(visible=False)
 
1004
  )
1005
  break
1006
 
@@ -1027,9 +1089,9 @@ def create_interface():
1027
  .replace("<", "_x13x_") \
1028
  .replace(">", "_x14x_") \
1029
  .replace("|", "_x15x_")
1030
-
1031
  save_url = save_url + "__" + str(uuid.uuid4()).replace("-", "_")
1032
-
1033
  save_dict = {
1034
  save_url: final_result
1035
  }
@@ -1040,7 +1102,7 @@ def create_interface():
1040
  annotated_image_path = final_image if final_image else original_image
1041
  print(f"[CONSOLE] Using image for dataset upload: {dataset_image_path} (original: {original_image}, final: {final_image})")
1042
  print(f"[CONSOLE] Using annotated image for display: {annotated_image_path} (original: {original_image}, final: {final_image})")
1043
-
1044
  if dataset_image_path and os.path.exists(dataset_image_path) and annotated_image_path and os.path.exists(annotated_image_path):
1045
  try:
1046
  # Load the original image using PIL
@@ -1063,16 +1125,20 @@ def create_interface():
1063
  print(f"[CONSOLE] Warning: Image path not found or invalid: {dataset_image_path}")
1064
  image_df = pd.DataFrame([{"id": save_url, "image": None, "annotated_image": None}])
1065
 
1066
- dataset_upload.update_dataset_with_new_splits(save_dict)
1067
- dataset_upload.update_dataset_with_new_images(image_df, scheduler=scheduler, dataset_dir=dataset_dir, jsonl_path=jsonl_path)
1068
-
 
 
 
1069
  # Show final results with annotated screenshot
1070
  yield (
1071
  final_status,
1072
  gr.update(visible=False), # Hide placeholder
1073
  gr.update(value=final_image, visible=True, label="🎯 Annotated Screenshot (Analysis Complete)") if final_image else gr.update(visible=False),
1074
  results_html,
1075
- gr.update(value=final_result, visible=True)
 
1076
  )
1077
 
1078
  # Clean up temporary files after successful display
@@ -1089,7 +1155,8 @@ def create_interface():
1089
  gr.update(visible=True), # Show placeholder again
1090
  gr.update(visible=False, label="Website Screenshot"), # Hide screenshot and reset label
1091
  "<div style='color: #ef4444; text-align: center; background-color: var(--block-background-fill); padding: 15px; border-radius: 8px; border: 1px solid #ef4444; opacity: 0.9;'>Analysis failed. Please check your Gemini API key and try again.</div>",
1092
- gr.update(visible=False)
 
1093
  )
1094
 
1095
  except Exception as e:
@@ -1103,7 +1170,8 @@ def create_interface():
1103
  gr.update(visible=True), # Show placeholder again
1104
  gr.update(visible=False, label="Website Screenshot"), # Hide screenshot and reset label
1105
  f"<div style='color: #ef4444; text-align: center; background-color: var(--block-background-fill); padding: 15px; border-radius: 8px; border: 1px solid #ef4444; opacity: 0.9;'>{error_msg}</div>",
1106
- gr.update(visible=False)
 
1107
  )
1108
  if e.__class__ == gr.exceptions.Error:
1109
  raise e
@@ -1113,7 +1181,7 @@ def create_interface():
1113
  analyze_url_btn.click(
1114
  fn=handle_url_analysis,
1115
  inputs=[url_input, gemini_api_key],
1116
- outputs=[status_text, screenshot_placeholder, screenshot_display, results_display, results_dataframe],
1117
  show_progress="full"
1118
  )
1119
 
@@ -1144,9 +1212,13 @@ if __name__ == "__main__":
1144
 
1145
  from py_files.utils import decrypt_system_prompts
1146
 
1147
- if not decrypt_system_prompts():
1148
- print(f"[CONSOLE] Failed to decrypt system prompts, exiting...")
1149
- exit(1)
 
 
 
 
1150
 
1151
  print(f"[CONSOLE] ===== STARTING GRADIO APPLICATION =====")
1152
  print(f"[CONSOLE] Creating Gradio interface...")
 
865
  results_display = gr.HTML(
866
  value="<div style='text-align: center; padding: 40px; color: var(--body-text-color); opacity: 0.7;'>Enter a URL and click analyze to see results here.</div>"
867
  )
 
 
 
 
 
868
 
869
  with gr.Column(scale=3):
870
  # Screenshot section - only screenshot in right column
 
927
  interactive=False
928
  )
929
 
930
+ # Detailed results table spanning both columns (full width)
931
+ results_dataframe = gr.Dataframe(
932
+ label="Detailed Results (Scroll right to see all columns)",
933
+ visible=False
934
+ )
935
+
936
+ # Download button for results CSV
937
+ download_btn = gr.DownloadButton(
938
+ label="📥 Download Results as CSV",
939
+ visible=False,
940
+ variant="secondary"
941
+ )
942
+
943
  # Event handlers
944
+ def save_results_to_csv(df, url):
945
+ """Save the results dataframe to a CSV file named after the analyzed site."""
946
+ if df is None or (isinstance(df, pd.DataFrame) and df.empty):
947
+ return None
948
+
949
+ # Create a safe filename from the URL
950
+ safe_filename = url.lower().replace("http://", "").replace("https://", "").strip().replace("www.", "") \
951
+ .replace(".", "_") \
952
+ .replace("/", "_") \
953
+ .replace("-", "_") \
954
+ .replace("=", "_") \
955
+ .replace("?", "_") \
956
+ .replace("&", "_") \
957
+ .replace("%", "_") \
958
+ .replace(":", "_") \
959
+ .replace("#", "_") \
960
+ .replace("'", "_") \
961
+ .replace('"', "_") \
962
+ .replace("*", "_") \
963
+ .replace("<", "_") \
964
+ .replace(">", "_") \
965
+ .replace("|", "_") \
966
+ .replace(" ", "_")
967
+
968
+ # Trim if too long and ensure it doesn't end with underscore
969
+ safe_filename = safe_filename[:100].rstrip("_")
970
+
971
+ # Create final filename
972
+ csv_filename = f"{safe_filename}.csv"
973
+
974
+ # Create a temporary file for download
975
+ temp_csv = tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.csv', prefix='analysis_')
976
+ csv_path = temp_csv.name
977
+ temp_csv.close()
978
+
979
+ # Save dataframe to CSV
980
+ if isinstance(df, pd.DataFrame):
981
+ df.to_csv(csv_path, index=False)
982
+ else:
983
+ # If it's not a DataFrame, try to convert it
984
+ pd.DataFrame(df).to_csv(csv_path, index=False)
985
+
986
+ # Rename to the site-specific filename for download
987
+ final_path = os.path.join(os.path.dirname(csv_path), csv_filename)
988
+ shutil.copy(csv_path, final_path)
989
+ os.remove(csv_path)
990
+
991
+ print(f"[CONSOLE] CSV file created for download: {final_path} (filename: {csv_filename})")
992
+ return final_path
993
+
994
  def handle_url_analysis(url, api_key):
995
  """Handle URL analysis with screenshot capture."""
996
  print(f"[CONSOLE] handle_url_analysis called with URL: {url}")
 
1007
  gr.update(visible=True), # Show placeholder initially
1008
  gr.update(visible=False), # Hide screenshot initially
1009
  "<div style='text-align: center; padding: 20px; color: var(--body-text-color); opacity: 0.7;'>Preparing analysis...</div>", # Clear previous errors
1010
+ gr.update(visible=False), # Hide dataframe
1011
+ gr.update(visible=False) # Hide download button
1012
  )
1013
 
1014
  analysis_generator = take_screenshot_and_process(url, api_key)
 
1035
  gr.update(visible=False), # Hide placeholder
1036
  gr.update(value=image_path, visible=True, label="📷 Original Screenshot"), # Show original screenshot
1037
  "<div style='text-align: center; padding: 20px; color: var(--body-text-color); opacity: 0.7;'>Analysis in progress...</div>", # Clear previous errors
1038
+ gr.update(visible=False),
1039
+ gr.update(visible=False) # Hide download button
1040
  )
1041
  else:
1042
  yield (
 
1044
  gr.update(visible=True), # Keep placeholder visible
1045
  gr.update(visible=False), # Hide screenshot
1046
  "<div style='text-align: center; padding: 20px; color: var(--body-text-color); opacity: 0.7;'>Analysis in progress...</div>", # Clear previous errors
1047
+ gr.update(visible=False),
1048
+ gr.update(visible=False) # Hide download button
1049
  )
1050
  else:
1051
  print(f"[CONSOLE] Received final result with {len(dataframe_result)} rows")
 
1061
  gr.update(visible=False), # Hide placeholder
1062
  gr.update(value=final_image, visible=True, label="🎯 Annotated Screenshot (Analysis Complete)") if final_image else gr.update(visible=False),
1063
  "<div style='text-align: center; padding: 20px; color: var(--body-text-color); opacity: 0.7;'>Processing results...</div>", # Clear previous errors
1064
+ gr.update(visible=False),
1065
+ gr.update(visible=False) # Hide download button
1066
  )
1067
  break
1068
 
 
1089
  .replace("<", "_x13x_") \
1090
  .replace(">", "_x14x_") \
1091
  .replace("|", "_x15x_")
1092
+
1093
  save_url = save_url + "__" + str(uuid.uuid4()).replace("-", "_")
1094
+
1095
  save_dict = {
1096
  save_url: final_result
1097
  }
 
1102
  annotated_image_path = final_image if final_image else original_image
1103
  print(f"[CONSOLE] Using image for dataset upload: {dataset_image_path} (original: {original_image}, final: {final_image})")
1104
  print(f"[CONSOLE] Using annotated image for display: {annotated_image_path} (original: {original_image}, final: {final_image})")
1105
+
1106
  if dataset_image_path and os.path.exists(dataset_image_path) and annotated_image_path and os.path.exists(annotated_image_path):
1107
  try:
1108
  # Load the original image using PIL
 
1125
  print(f"[CONSOLE] Warning: Image path not found or invalid: {dataset_image_path}")
1126
  image_df = pd.DataFrame([{"id": save_url, "image": None, "annotated_image": None}])
1127
 
1128
+ # dataset_upload.update_dataset_with_new_splits(save_dict)
1129
+ # dataset_upload.update_dataset_with_new_images(image_df, scheduler=scheduler, dataset_dir=dataset_dir, jsonl_path=jsonl_path)
1130
+
1131
+ # Prepare CSV for download
1132
+ csv_file_path = save_results_to_csv(final_result, url)
1133
+
1134
  # Show final results with annotated screenshot
1135
  yield (
1136
  final_status,
1137
  gr.update(visible=False), # Hide placeholder
1138
  gr.update(value=final_image, visible=True, label="🎯 Annotated Screenshot (Analysis Complete)") if final_image else gr.update(visible=False),
1139
  results_html,
1140
+ gr.update(value=final_result, visible=True),
1141
+ gr.update(value=csv_file_path, visible=True) if csv_file_path else gr.update(visible=False)
1142
  )
1143
 
1144
  # Clean up temporary files after successful display
 
1155
  gr.update(visible=True), # Show placeholder again
1156
  gr.update(visible=False, label="Website Screenshot"), # Hide screenshot and reset label
1157
  "<div style='color: #ef4444; text-align: center; background-color: var(--block-background-fill); padding: 15px; border-radius: 8px; border: 1px solid #ef4444; opacity: 0.9;'>Analysis failed. Please check your Gemini API key and try again.</div>",
1158
+ gr.update(visible=False),
1159
+ gr.update(visible=False) # Hide download button
1160
  )
1161
 
1162
  except Exception as e:
 
1170
  gr.update(visible=True), # Show placeholder again
1171
  gr.update(visible=False, label="Website Screenshot"), # Hide screenshot and reset label
1172
  f"<div style='color: #ef4444; text-align: center; background-color: var(--block-background-fill); padding: 15px; border-radius: 8px; border: 1px solid #ef4444; opacity: 0.9;'>{error_msg}</div>",
1173
+ gr.update(visible=False),
1174
+ gr.update(visible=False) # Hide download button
1175
  )
1176
  if e.__class__ == gr.exceptions.Error:
1177
  raise e
 
1181
  analyze_url_btn.click(
1182
  fn=handle_url_analysis,
1183
  inputs=[url_input, gemini_api_key],
1184
+ outputs=[status_text, screenshot_placeholder, screenshot_display, results_display, results_dataframe, download_btn],
1185
  show_progress="full"
1186
  )
1187
 
 
1212
 
1213
  from py_files.utils import decrypt_system_prompts
1214
 
1215
+ if os.path.exists("./system_prompt.txt") and os.path.exists("./system_prompt_thinking.txt"):
1216
+ print(f"[CONSOLE] System prompts already decrypted, skipping decryption step")
1217
+ else:
1218
+ print(f"[CONSOLE] Decrypting system prompts...")
1219
+ if not decrypt_system_prompts():
1220
+ print(f"[CONSOLE] Failed to decrypt system prompts, exiting...")
1221
+ exit(1)
1222
 
1223
  print(f"[CONSOLE] ===== STARTING GRADIO APPLICATION =====")
1224
  print(f"[CONSOLE] Creating Gradio interface...")