Spaces:
				
			
			
	
			
			
					
		Running
		
	
	
	
			
			
	
	
	
	
		
		
					
		Running
		
	Commit 
							
							·
						
						2e6b21d
	
1
								Parent(s):
							
							32c38a5
								
Update
Browse files
    	
        app.py
    CHANGED
    
    | @@ -39,6 +39,7 @@ examples_data = [ | |
| 39 | 
             
                    "screencoder/data/input/test3.png"
         | 
| 40 | 
             
                ],
         | 
| 41 | 
             
            ]
         | 
|  | |
| 42 |  | 
| 43 | 
             
            # TAILWIND_SCRIPT = "<script src='https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4'></script>"
         | 
| 44 |  | 
| @@ -156,93 +157,99 @@ def render_preview(code: str, width: int, height: int, scale: float) -> str: | |
| 156 | 
             
                """
         | 
| 157 | 
             
                return iframe_html
         | 
| 158 |  | 
| 159 | 
            -
            def process_and_generate( | 
| 160 | 
             
                """
         | 
| 161 | 
            -
                Main processing pipeline: takes an image, generates code, creates a downloadable
         | 
| 162 | 
            -
                package, and returns the initial preview and code outputs.
         | 
| 163 | 
             
                """
         | 
| 164 | 
             
                final_image_path = ""
         | 
| 165 | 
             
                is_temp_file = False
         | 
| 166 | 
            -
             | 
| 167 | 
            -
             | 
| 168 | 
            -
                 | 
|  | |
|  | |
| 169 | 
             
                    is_temp_file = True
         | 
| 170 | 
             
                    with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as tmp:
         | 
| 171 | 
            -
                         | 
|  | |
| 172 | 
             
                        final_image_path = tmp.name
         | 
|  | |
|  | |
| 173 | 
             
                else:
         | 
| 174 | 
            -
                     | 
| 175 | 
            -
             | 
|  | |
| 176 | 
             
                instructions = {
         | 
| 177 | 
             
                    "sidebar": sidebar_prompt, "header": header_prompt,
         | 
| 178 | 
             
                    "navigation": navigation_prompt, "main content": main_content_prompt
         | 
| 179 | 
             
                }
         | 
| 180 | 
            -
                 | 
| 181 |  | 
| 182 | 
             
                if not run_id: # Handle potential errors from the generator
         | 
| 183 | 
            -
                     | 
|  | |
| 184 |  | 
| 185 | 
            -
                #  | 
| 186 | 
            -
                 | 
| 187 | 
            -
             | 
| 188 | 
            -
             | 
| 189 | 
            -
                
         | 
| 190 | 
            -
                print(f"Processing HTML for run_id: {run_id}")
         | 
| 191 | 
            -
                
         | 
| 192 | 
            -
                # Fix CSS and JS paths to work with Gradio's file serving
         | 
| 193 | 
            -
                try:
         | 
| 194 | 
            -
                    output_dir = base_dir / 'screencoder' / 'data' / 'output' / run_id
         | 
| 195 | 
            -
                    soup = patch_css_js_paths(soup, output_dir)
         | 
| 196 | 
            -
                except Exception as e:
         | 
| 197 | 
            -
                    print(f"Error fixing CSS/JS paths: {e}")
         | 
| 198 | 
            -
                
         | 
| 199 | 
            -
                for img in soup.find_all('img'):
         | 
| 200 | 
            -
                    if img.get('src') and not img['src'].startswith(('http', 'data:')):
         | 
| 201 | 
            -
                        original_src = img['src']
         | 
| 202 | 
            -
                        print(f"Processing image: {original_src}")
         | 
| 203 | 
            -
                        
         | 
| 204 | 
            -
                        # In HF Spaces, paths can be tricky. We'll rely on the fact
         | 
| 205 | 
            -
                        # that the image replacer creates a predictable structure.
         | 
| 206 | 
            -
                        img_path = base_dir / 'screencoder' / 'data' / 'output' / run_id / original_src
         | 
| 207 |  | 
| 208 | 
            -
             | 
| 209 | 
            -
             | 
| 210 | 
            -
             | 
| 211 | 
            -
             | 
| 212 | 
            -
             | 
| 213 | 
            -
             | 
| 214 | 
            -
             | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 215 | 
             
                            else:
         | 
| 216 | 
            -
                                 | 
| 217 | 
            -
             | 
| 218 | 
            -
             | 
| 219 | 
            -
             | 
| 220 | 
            -
             | 
| 221 | 
            -
                            img['src'] = original_src
         | 
| 222 | 
            -
                
         | 
| 223 | 
            -
                html_content = str(soup)
         | 
| 224 |  | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 225 | 
             
                output_dir = base_dir / 'screencoder' / 'data' / 'output' / run_id
         | 
| 226 | 
             
                packages_dir = base_dir / 'screencoder' / 'data' / 'packages'
         | 
| 227 | 
             
                packages_dir.mkdir(exist_ok=True)
         | 
| 228 |  | 
| 229 | 
            -
                shutil.make_archive(str(packages_dir / run_id), 'zip', str(output_dir))
         | 
| 230 | 
             
                package_path = packages_dir / f'{run_id}.zip'
         | 
|  | |
| 231 | 
             
                package_url = f'/file={str(package_path)}'
         | 
| 232 |  | 
| 233 | 
             
                if is_temp_file:
         | 
| 234 | 
             
                    os.unlink(final_image_path)
         | 
| 235 |  | 
| 236 | 
            -
                 | 
|  | |
| 237 |  | 
| 238 | 
            -
                return initial_preview, html_content, gr.update(value=package_url, visible=True)
         | 
| 239 |  | 
| 240 | 
             
            with gr.Blocks() as demo:
         | 
| 241 | 
             
                gr.Markdown("# ScreenCoder: Screenshot to Code")
         | 
| 242 | 
             
                with gr.Row():
         | 
| 243 | 
             
                    with gr.Column(scale=1):
         | 
| 244 | 
             
                        gr.Markdown("### Step 1: Provide an Image")
         | 
| 245 | 
            -
                        active_image = gr.Image(type=" | 
| 246 | 
             
                        upload_button = gr.UploadButton("Click to Upload", file_types=["image"], variant="primary")
         | 
| 247 |  | 
| 248 | 
             
                        gr.Markdown("### Step 2: Write Prompts (Optional)")
         | 
| @@ -259,34 +266,47 @@ with gr.Blocks() as demo: | |
| 259 | 
             
                            with gr.TabItem("Preview"):
         | 
| 260 | 
             
                                with gr.Row():
         | 
| 261 | 
             
                                    scale_slider = gr.Slider(0.2, 1.5, value=0.7, step=0.05, label="Zoom")
         | 
| 262 | 
            -
                                    width_slider = gr.Slider(400,  | 
| 263 | 
            -
                                    height_slider = gr.Slider(300,  | 
| 264 |  | 
| 265 | 
             
                                html_preview = gr.HTML(label="Rendered HTML", show_label=False)
         | 
| 266 | 
            -
             | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 267 | 
             
                            with gr.TabItem("Code"):
         | 
| 268 | 
             
                                html_code_output = gr.Code(label="Generated HTML", language="html")
         | 
| 269 |  | 
| 270 | 
             
                        download_button = gr.Button("⬇️ Download Package", visible=False, variant="secondary")
         | 
| 271 |  | 
| 272 | 
             
                gr.Examples(
         | 
| 273 | 
            -
                    examples= | 
| 274 | 
            -
                     | 
| 275 | 
            -
                    inputs=[gr.State(examples_data[0][0])],
         | 
| 276 | 
            -
                    outputs=[active_image],
         | 
| 277 | 
             
                    cache_examples=False,
         | 
|  | |
| 278 | 
             
                )
         | 
| 279 |  | 
| 280 | 
            -
                 | 
|  | |
|  | |
|  | |
| 281 |  | 
| 282 | 
            -
                 | 
| 283 | 
            -
                     | 
|  | |
|  | |
|  | |
|  | |
| 284 |  | 
| 285 | 
             
                demo.load(
         | 
| 286 | 
            -
                    lambda: (examples_data[0][0], examples_data[0][ | 
| 287 | 
             
                )
         | 
| 288 |  | 
| 289 | 
             
                def handle_upload(uploaded_image_np):
         | 
|  | |
| 290 | 
             
                    return uploaded_image_np, None, gr.update(visible=False)
         | 
| 291 |  | 
| 292 | 
             
                upload_button.upload(handle_upload, upload_button, [active_image, active_image_path_state, download_button])
         | 
| @@ -294,7 +314,7 @@ with gr.Blocks() as demo: | |
| 294 | 
             
                generate_btn.click(
         | 
| 295 | 
             
                    process_and_generate,
         | 
| 296 | 
             
                    [active_image, active_image_path_state, sidebar_prompt, header_prompt, navigation_prompt, main_content_prompt],
         | 
| 297 | 
            -
                    [html_preview,  | 
| 298 | 
             
                    show_progress="full"
         | 
| 299 | 
             
                )
         | 
| 300 |  | 
| @@ -302,11 +322,20 @@ with gr.Blocks() as demo: | |
| 302 | 
             
                for control in preview_controls:
         | 
| 303 | 
             
                    control.change(
         | 
| 304 | 
             
                        render_preview,
         | 
| 305 | 
            -
                        [ | 
| 306 | 
             
                        html_preview,
         | 
| 307 | 
             
                        show_progress=True
         | 
| 308 | 
             
                    )
         | 
| 309 |  | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 310 | 
             
                download_button.click(None, download_button, None, js= \
         | 
| 311 | 
             
                    "(url) => { const link = document.createElement('a'); link.href = url; link.download = ''; document.body.appendChild(link); link.click(); document.body.removeChild(link); }")
         | 
| 312 |  | 
| @@ -317,10 +346,7 @@ allowed_paths = [ | |
| 317 | 
             
                str(base_dir / 'screencoder' / 'data' / 'packages')
         | 
| 318 | 
             
            ]
         | 
| 319 |  | 
| 320 | 
            -
            # Add all example file paths to allowed_paths to ensure they are accessible
         | 
| 321 | 
             
            for example in examples_data:
         | 
| 322 | 
            -
                # HF Spaces: Ensure the path is absolute by joining with base_dir
         | 
| 323 | 
            -
                # The example path is relative, so we join it with the base_dir to make it absolute.
         | 
| 324 | 
             
                example_abs_path = (base_dir / example[0]).resolve()
         | 
| 325 | 
             
                example_dir = example_abs_path.parent
         | 
| 326 | 
             
                if str(example_dir) not in allowed_paths:
         | 
|  | |
| 39 | 
             
                    "screencoder/data/input/test3.png"
         | 
| 40 | 
             
                ],
         | 
| 41 | 
             
            ]
         | 
| 42 | 
            +
            example_rows = [row[:5] for row in examples_data]
         | 
| 43 |  | 
| 44 | 
             
            # TAILWIND_SCRIPT = "<script src='https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4'></script>"
         | 
| 45 |  | 
|  | |
| 157 | 
             
                """
         | 
| 158 | 
             
                return iframe_html
         | 
| 159 |  | 
| 160 | 
            +
            def process_and_generate(image_input, image_path_from_state, sidebar_prompt, header_prompt, navigation_prompt, main_content_prompt):
         | 
| 161 | 
             
                """
         | 
| 162 | 
            +
                Main processing pipeline: takes an image (path or numpy), generates code, creates a downloadable
         | 
| 163 | 
            +
                package, and returns the initial preview and code outputs for both layout and final versions.
         | 
| 164 | 
             
                """
         | 
| 165 | 
             
                final_image_path = ""
         | 
| 166 | 
             
                is_temp_file = False
         | 
| 167 | 
            +
             | 
| 168 | 
            +
                # Handle image_input which can be a numpy array (from upload) or a string (from example)
         | 
| 169 | 
            +
                if isinstance(image_input, str) and os.path.exists(image_input):
         | 
| 170 | 
            +
                    final_image_path = image_input
         | 
| 171 | 
            +
                elif image_input is not None:  # Assumes numpy array
         | 
| 172 | 
             
                    is_temp_file = True
         | 
| 173 | 
             
                    with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as tmp:
         | 
| 174 | 
            +
                        # Gradio Image component provides RGB numpy array
         | 
| 175 | 
            +
                        cv2.imwrite(tmp.name, cv2.cvtColor(image_input, cv2.COLOR_RGB2BGR))
         | 
| 176 | 
             
                        final_image_path = tmp.name
         | 
| 177 | 
            +
                elif image_path_from_state:
         | 
| 178 | 
            +
                    final_image_path = image_path_from_state
         | 
| 179 | 
             
                else:
         | 
| 180 | 
            +
                    # Return empty values for all outputs
         | 
| 181 | 
            +
                    return "No image provided.", "", "", "Please upload or select an image.", gr.update(visible=False), None
         | 
| 182 | 
            +
                
         | 
| 183 | 
             
                instructions = {
         | 
| 184 | 
             
                    "sidebar": sidebar_prompt, "header": header_prompt,
         | 
| 185 | 
             
                    "navigation": navigation_prompt, "main content": main_content_prompt
         | 
| 186 | 
             
                }
         | 
| 187 | 
            +
                layout_html, final_html, run_id = generate_html_for_demo(final_image_path, instructions)
         | 
| 188 |  | 
| 189 | 
             
                if not run_id: # Handle potential errors from the generator
         | 
| 190 | 
            +
                    error_message = f"Generation failed. Error: {layout_html}"
         | 
| 191 | 
            +
                    return error_message, "", "", error_message, gr.update(visible=False), None
         | 
| 192 |  | 
| 193 | 
            +
                # --- Helper function to process HTML content ---
         | 
| 194 | 
            +
                def process_html(html_content, run_id):
         | 
| 195 | 
            +
                    if not html_content:
         | 
| 196 | 
            +
                        return "", "" # Return empty strings if content is missing
         | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 197 |  | 
| 198 | 
            +
                    base_dir = Path(__file__).parent.resolve()
         | 
| 199 | 
            +
                    soup = BeautifulSoup(html_content, 'html.parser')
         | 
| 200 | 
            +
                    
         | 
| 201 | 
            +
                    # Fix CSS and JS paths
         | 
| 202 | 
            +
                    try:
         | 
| 203 | 
            +
                        output_dir = base_dir / 'screencoder' / 'data' / 'output' / run_id
         | 
| 204 | 
            +
                        soup = patch_css_js_paths(soup, output_dir)
         | 
| 205 | 
            +
                    except Exception as e:
         | 
| 206 | 
            +
                        print(f"Error fixing CSS/JS paths: {e}")
         | 
| 207 | 
            +
                    
         | 
| 208 | 
            +
                    # Convert image paths to data URLs
         | 
| 209 | 
            +
                    for img in soup.find_all('img'):
         | 
| 210 | 
            +
                        if img.get('src') and not img['src'].startswith(('http', 'data:')):
         | 
| 211 | 
            +
                            original_src = img['src']
         | 
| 212 | 
            +
                            img_path = base_dir / 'screencoder' / 'data' / 'output' / run_id / original_src
         | 
| 213 | 
            +
                            if img_path.exists():
         | 
| 214 | 
            +
                                data_url = image_to_data_url(str(img_path))
         | 
| 215 | 
            +
                                if data_url:
         | 
| 216 | 
            +
                                    img['src'] = data_url
         | 
| 217 | 
            +
                                else:
         | 
| 218 | 
            +
                                    img['src'] = f'/file={str(img_path)}'
         | 
| 219 | 
             
                            else:
         | 
| 220 | 
            +
                                img['src'] = original_src # Keep original if not found
         | 
| 221 | 
            +
                    
         | 
| 222 | 
            +
                    processed_html = str(soup)
         | 
| 223 | 
            +
                    preview = render_preview(processed_html, 1920, 1080, 0.7)
         | 
| 224 | 
            +
                    return preview, processed_html
         | 
|  | |
|  | |
|  | |
| 225 |  | 
| 226 | 
            +
                # --- Process both HTML versions ---
         | 
| 227 | 
            +
                layout_preview, layout_code = process_html(layout_html, run_id)
         | 
| 228 | 
            +
                final_preview, final_code = process_html(final_html, run_id)
         | 
| 229 | 
            +
             | 
| 230 | 
            +
                # --- Package the output ---
         | 
| 231 | 
            +
                base_dir = Path(__file__).parent.resolve()
         | 
| 232 | 
             
                output_dir = base_dir / 'screencoder' / 'data' / 'output' / run_id
         | 
| 233 | 
             
                packages_dir = base_dir / 'screencoder' / 'data' / 'packages'
         | 
| 234 | 
             
                packages_dir.mkdir(exist_ok=True)
         | 
| 235 |  | 
|  | |
| 236 | 
             
                package_path = packages_dir / f'{run_id}.zip'
         | 
| 237 | 
            +
                shutil.make_archive(str(packages_dir / run_id), 'zip', str(output_dir))
         | 
| 238 | 
             
                package_url = f'/file={str(package_path)}'
         | 
| 239 |  | 
| 240 | 
             
                if is_temp_file:
         | 
| 241 | 
             
                    os.unlink(final_image_path)
         | 
| 242 |  | 
| 243 | 
            +
                # Return all the outputs, including for the state objects
         | 
| 244 | 
            +
                return layout_preview, final_preview, layout_code, final_code, gr.update(value=package_url, visible=True)
         | 
| 245 |  | 
|  | |
| 246 |  | 
| 247 | 
             
            with gr.Blocks() as demo:
         | 
| 248 | 
             
                gr.Markdown("# ScreenCoder: Screenshot to Code")
         | 
| 249 | 
             
                with gr.Row():
         | 
| 250 | 
             
                    with gr.Column(scale=1):
         | 
| 251 | 
             
                        gr.Markdown("### Step 1: Provide an Image")
         | 
| 252 | 
            +
                        active_image = gr.Image(type="filepath", height=400)
         | 
| 253 | 
             
                        upload_button = gr.UploadButton("Click to Upload", file_types=["image"], variant="primary")
         | 
| 254 |  | 
| 255 | 
             
                        gr.Markdown("### Step 2: Write Prompts (Optional)")
         | 
|  | |
| 266 | 
             
                            with gr.TabItem("Preview"):
         | 
| 267 | 
             
                                with gr.Row():
         | 
| 268 | 
             
                                    scale_slider = gr.Slider(0.2, 1.5, value=0.7, step=0.05, label="Zoom")
         | 
| 269 | 
            +
                                    width_slider = gr.Slider(400, 2000, value=1920, step=100, label="Canvas Width (px)")
         | 
| 270 | 
            +
                                    height_slider = gr.Slider(300, 1200, value=1080, step=50, label="Canvas Height (px)")
         | 
| 271 |  | 
| 272 | 
             
                                html_preview = gr.HTML(label="Rendered HTML", show_label=False)
         | 
| 273 | 
            +
                            with gr.TabItem("Preview With Placeholder"):
         | 
| 274 | 
            +
                                with gr.Row():
         | 
| 275 | 
            +
                                    scale_slider_with_placeholder = gr.Slider(0.2, 1.5, value=0.7, step=0.05, label="Zoom")
         | 
| 276 | 
            +
                                    width_slider_with_placeholder = gr.Slider(400, 2000, value=1920, step=100, label="Canvas Width (px)")
         | 
| 277 | 
            +
                                    height_slider_with_placeholder = gr.Slider(300, 1200, value=1080, step=50, label="Canvas Height (px)")
         | 
| 278 | 
            +
                                
         | 
| 279 | 
            +
                                html_preview_with_placeholder = gr.HTML(label="Rendered HTML", show_label=False)
         | 
| 280 | 
             
                            with gr.TabItem("Code"):
         | 
| 281 | 
             
                                html_code_output = gr.Code(label="Generated HTML", language="html")
         | 
| 282 |  | 
| 283 | 
             
                        download_button = gr.Button("⬇️ Download Package", visible=False, variant="secondary")
         | 
| 284 |  | 
| 285 | 
             
                gr.Examples(
         | 
| 286 | 
            +
                    examples=example_rows,
         | 
| 287 | 
            +
                    inputs=[active_image, sidebar_prompt, header_prompt, navigation_prompt, main_content_prompt],
         | 
|  | |
|  | |
| 288 | 
             
                    cache_examples=False,
         | 
| 289 | 
            +
                    label="Examples"
         | 
| 290 | 
             
                )
         | 
| 291 |  | 
| 292 | 
            +
                # State to hold the HTML content for each preview tab
         | 
| 293 | 
            +
                layout_code_state = gr.State("")
         | 
| 294 | 
            +
                final_code_state = gr.State("")
         | 
| 295 | 
            +
                active_image_path_state = gr.State()
         | 
| 296 |  | 
| 297 | 
            +
                active_image.change(
         | 
| 298 | 
            +
                    lambda p: p if isinstance(p, str) else None,
         | 
| 299 | 
            +
                    inputs=active_image,
         | 
| 300 | 
            +
                    outputs=active_image_path_state,
         | 
| 301 | 
            +
                    show_progress=False
         | 
| 302 | 
            +
                )
         | 
| 303 |  | 
| 304 | 
             
                demo.load(
         | 
| 305 | 
            +
                    lambda: (examples_data[0][0], examples_data[0][0]), None, [active_image, active_image_path_state]
         | 
| 306 | 
             
                )
         | 
| 307 |  | 
| 308 | 
             
                def handle_upload(uploaded_image_np):
         | 
| 309 | 
            +
                    # When a new image is uploaded, it's numpy. Clear the path state.
         | 
| 310 | 
             
                    return uploaded_image_np, None, gr.update(visible=False)
         | 
| 311 |  | 
| 312 | 
             
                upload_button.upload(handle_upload, upload_button, [active_image, active_image_path_state, download_button])
         | 
|  | |
| 314 | 
             
                generate_btn.click(
         | 
| 315 | 
             
                    process_and_generate,
         | 
| 316 | 
             
                    [active_image, active_image_path_state, sidebar_prompt, header_prompt, navigation_prompt, main_content_prompt],
         | 
| 317 | 
            +
                    [html_preview, html_preview_with_placeholder, layout_code_state, final_code_state, download_button],
         | 
| 318 | 
             
                    show_progress="full"
         | 
| 319 | 
             
                )
         | 
| 320 |  | 
|  | |
| 322 | 
             
                for control in preview_controls:
         | 
| 323 | 
             
                    control.change(
         | 
| 324 | 
             
                        render_preview,
         | 
| 325 | 
            +
                        [layout_code_state, width_slider, height_slider, scale_slider],
         | 
| 326 | 
             
                        html_preview,
         | 
| 327 | 
             
                        show_progress=True
         | 
| 328 | 
             
                    )
         | 
| 329 |  | 
| 330 | 
            +
                preview_controls_with_placeholder = [scale_slider_with_placeholder, width_slider_with_placeholder, height_slider_with_placeholder]
         | 
| 331 | 
            +
                for control in preview_controls_with_placeholder:
         | 
| 332 | 
            +
                    control.change(
         | 
| 333 | 
            +
                        render_preview,
         | 
| 334 | 
            +
                        [final_code_state, width_slider_with_placeholder, height_slider_with_placeholder, scale_slider_with_placeholder],
         | 
| 335 | 
            +
                        html_preview_with_placeholder,
         | 
| 336 | 
            +
                        show_progress=True
         | 
| 337 | 
            +
                    )
         | 
| 338 | 
            +
             | 
| 339 | 
             
                download_button.click(None, download_button, None, js= \
         | 
| 340 | 
             
                    "(url) => { const link = document.createElement('a'); link.href = url; link.download = ''; document.body.appendChild(link); link.click(); document.body.removeChild(link); }")
         | 
| 341 |  | 
|  | |
| 346 | 
             
                str(base_dir / 'screencoder' / 'data' / 'packages')
         | 
| 347 | 
             
            ]
         | 
| 348 |  | 
|  | |
| 349 | 
             
            for example in examples_data:
         | 
|  | |
|  | |
| 350 | 
             
                example_abs_path = (base_dir / example[0]).resolve()
         | 
| 351 | 
             
                example_dir = example_abs_path.parent
         | 
| 352 | 
             
                if str(example_dir) not in allowed_paths:
         | 
    	
        screencoder/data/tmp/daca8e45-368a-4a1b-97dd-8c264e64abea/daca8e45-368a-4a1b-97dd-8c264e64abea.png
    ADDED
    
    |   | 
| Git LFS Details
 | 
    	
        screencoder/main.py
    CHANGED
    
    | @@ -103,21 +103,32 @@ def generate_html_for_demo(image_path, instructions): | |
| 103 | 
             
                    run_script_with_run_id("mapping.py", run_id)
         | 
| 104 | 
             
                    run_script_with_run_id("image_replacer.py", run_id)
         | 
| 105 |  | 
| 106 | 
            -
                    # 3. Read the  | 
|  | |
| 107 | 
             
                    final_html_path = output_dir / f"{run_id}_layout_final.html"
         | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 108 | 
             
                    if final_html_path.exists():
         | 
| 109 | 
             
                        with open(final_html_path, 'r', encoding='utf-8') as f:
         | 
| 110 | 
            -
                             | 
| 111 | 
            -
                        print(f"Successfully generated HTML for run_id: {run_id}")
         | 
| 112 | 
            -
                        return  | 
| 113 | 
             
                    else:
         | 
| 114 | 
             
                        error_msg = f"Error: Final HTML file not found for run_id: {run_id}"
         | 
| 115 | 
            -
                        return error_msg, run_id
         | 
| 116 |  | 
| 117 | 
             
                except Exception as e:
         | 
| 118 | 
             
                    error_msg = f"An error occurred: {e}"
         | 
| 119 | 
             
                    print(f"An error occurred during the workflow for run_id {run_id}: {e}")
         | 
| 120 | 
            -
                     | 
|  | |
| 121 | 
             
                finally:
         | 
| 122 | 
             
                    # 4. Cleanup: Remove temporary directories
         | 
| 123 | 
             
                    try:
         | 
|  | |
| 103 | 
             
                    run_script_with_run_id("mapping.py", run_id)
         | 
| 104 | 
             
                    run_script_with_run_id("image_replacer.py", run_id)
         | 
| 105 |  | 
| 106 | 
            +
                    # 3. Read the generated HTML files
         | 
| 107 | 
            +
                    layout_html_path = output_dir / f"{run_id}_layout.html"
         | 
| 108 | 
             
                    final_html_path = output_dir / f"{run_id}_layout_final.html"
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                    layout_html_content = ""
         | 
| 111 | 
            +
                    if layout_html_path.exists():
         | 
| 112 | 
            +
                        with open(layout_html_path, 'r', encoding='utf-8') as f:
         | 
| 113 | 
            +
                            layout_html_content = f.read()
         | 
| 114 | 
            +
                        print(f"Successfully read layout HTML for run_id: {run_id}")
         | 
| 115 | 
            +
                    else:
         | 
| 116 | 
            +
                        print(f"Warning: Layout HTML file not found for run_id: {run_id}")
         | 
| 117 | 
            +
             | 
| 118 | 
             
                    if final_html_path.exists():
         | 
| 119 | 
             
                        with open(final_html_path, 'r', encoding='utf-8') as f:
         | 
| 120 | 
            +
                            final_html_content = f.read()
         | 
| 121 | 
            +
                        print(f"Successfully generated final HTML for run_id: {run_id}")
         | 
| 122 | 
            +
                        return layout_html_content, final_html_content, run_id
         | 
| 123 | 
             
                    else:
         | 
| 124 | 
             
                        error_msg = f"Error: Final HTML file not found for run_id: {run_id}"
         | 
| 125 | 
            +
                        return error_msg, None, run_id
         | 
| 126 |  | 
| 127 | 
             
                except Exception as e:
         | 
| 128 | 
             
                    error_msg = f"An error occurred: {e}"
         | 
| 129 | 
             
                    print(f"An error occurred during the workflow for run_id {run_id}: {e}")
         | 
| 130 | 
            +
                    # Return signature needs to match success case
         | 
| 131 | 
            +
                    return error_msg, None, run_id
         | 
| 132 | 
             
                finally:
         | 
| 133 | 
             
                    # 4. Cleanup: Remove temporary directories
         | 
| 134 | 
             
                    try:
         |