"""UI components and logic for the Ada Assistant Gradio interface.""" import gradio as gr class AdaAssistantUI: """Ada Assistant Gradio UI class that manages the web interface.""" def __init__(self, project_handler): """Initialize the UI with a project handler.""" self.project_handler = project_handler def extract_project(self, file): """Extract uploaded project""" if file is None: return "No file uploaded" try: # Extract zip file extracted_path = self.project_handler.unzip_project(file.name) return extracted_path except Exception as e: return f"Error processing file: {str(e)}" def handle_zip_upload(self, zip_file): """Handle zip file upload and extraction""" if zip_file is None: return None, "No zip file uploaded" try: # Extract the project extracted_path = self.extract_project(zip_file) return extracted_path, f"Project extracted to: {extracted_path}" except Exception as e: return None, f"Error processing zip file: {str(e)}" def handle_file_selection(self, selected_file): """Handle file selection from FileExplorer""" if not selected_file: return "", "", "", gr.Markdown(visible=False), gr.Code(visible=False), gr.Code(visible=False) # Check if it's an Ada file if not (selected_file.endswith('.ads') or selected_file.endswith('.adb')): return "", "", "", gr.Markdown(visible=False), gr.Code(visible=False), gr.Code(visible=False) try: # Read the Ada file content with open(selected_file, 'r', encoding='utf-8') as f: ada_code = f.read() # Process Ada code: analyze, convert, and generate tests analysis_result, python_code, unit_tests = self.project_handler.process_ada_file(ada_code) # Return markdown analysis, python code, and unit tests return analysis_result, python_code, unit_tests, gr.Markdown(visible=True), gr.Code(visible=True), gr.Code(visible=True) except Exception as e: error_markdown = f"# Error\n\nError processing file: {str(e)}" return error_markdown, "", "", gr.Markdown(visible=True), gr.Code(visible=False), gr.Code(visible=False) @staticmethod def update_explorer(path): """Update file explorer when path changes""" if path: return gr.FileExplorer(root_dir=path, visible=True) return gr.FileExplorer(visible=False) def handle_convert_download(self, extracted_path): """Handle convert and download with access to project_handler""" zip_path = self.project_handler.convert_and_download_project(extracted_path) if zip_path: return gr.File(value=zip_path, visible=True) return gr.File(visible=False) def create_interface(self): """Create the main Gradio interface""" with gr.Blocks(title="Ada Assistant - Project Analyzer") as app: gr.Markdown("# Ada Assistant - Project Analyzer") gr.Markdown("Upload a zip file containing your Ada project to extract and explore the code structure.") with gr.Row(): with gr.Column(scale=1): # Zip file upload with drag & drop zip_input = gr.File( label="Upload Project (ZIP)", file_types=[".zip"], type="filepath" ) # Project info display project_info = gr.Textbox( label="Project Status", value="No project loaded", interactive=False ) with gr.Column(scale=2): # File explorer for extracted project file_explorer = gr.FileExplorer( label="Project Structure", visible=False, file_count="single" ) with gr.Row(): with gr.Column(scale=1): # Analysis results display analysis_results = gr.Markdown( label="Business Logic Analysis", value="Select file to view analysis", visible=True ) with gr.Column(scale=1): # Python code display python_code_display = gr.Code( label="Converted Python Code", language="python", lines=20, visible=True ) with gr.Column(scale=1): # Unit tests display unit_tests_display = gr.Code( label="Generated Unit Tests", language="python", lines=20, visible=True ) with gr.Row(): # Convert & Download button convert_download_btn = gr.Button("Convert & Download") # Download component for the zip file download_file = gr.File(label="Download Converted Project", visible=False) # Hidden state to store extracted path extracted_path_state = gr.State() # Handle zip file upload zip_input.upload( fn=self.handle_zip_upload, inputs=[zip_input], outputs=[extracted_path_state, project_info] ) # Update file explorer when path changes extracted_path_state.change( fn=self.update_explorer, inputs=[extracted_path_state], outputs=[file_explorer] ) # Handle file selection file_explorer.change( fn=self.handle_file_selection, inputs=[file_explorer], outputs=[analysis_results, python_code_display, unit_tests_display, analysis_results, python_code_display, unit_tests_display] ) # Handle convert & download button click convert_download_btn.click( fn=self.handle_convert_download, inputs=[extracted_path_state], outputs=[download_file] ) return app