Spaces:
Running
Running
import subprocess | |
import sys | |
import os | |
import json | |
import uuid | |
import shutil | |
from PIL import Image | |
from pathlib import Path | |
# This function is now more robust, injecting the prompt into a temporary copy of the generator. | |
def inject_prompt_to_generator(prompt_text, temp_generator_path): | |
if not prompt_text: | |
return | |
user_instruction = { | |
"sidebar": "Make all icons look better; fill in relevant English text; beautify the layout.", | |
"header": "Make the Google logo look better; change the avatar color to be more appealing.", | |
"navigation": "Please beautify the layout.", | |
"main content": prompt_text | |
} | |
with open(temp_generator_path, 'r', encoding='utf-8') as f: | |
content = f.read() | |
start_marker = "user_instruction = {" | |
end_marker = "}" | |
start_index = content.find(start_marker) | |
end_index = content.find(end_marker, start_index) | |
if start_index != -1 and end_index != -1: | |
dict_str = f"user_instruction = {json.dumps(user_instruction, indent=4)}" | |
content = content[:start_index] + dict_str + content[end_index+1:] | |
with open(temp_generator_path, 'w', encoding='utf-8') as f: | |
f.write(content) | |
def run_script_with_run_id(script_name, run_id, instructions=None): | |
"""Executes a script with a specific run_id and optional instructions.""" | |
# HF Spaces: Use absolute paths based on the script's location | |
screencoder_dir = Path(__file__).parent.resolve() | |
script_path = screencoder_dir / script_name | |
if not script_path.exists(): | |
# Handle scripts inside subdirectories like UIED/ | |
script_path = screencoder_dir / "UIED" / script_name | |
command = [sys.executable, str(script_path), "--run_id", run_id] | |
# Add instructions to the command if provided | |
if instructions and "html_generator.py" in str(script_path): | |
instructions_json = json.dumps(instructions) | |
command.extend(["--instructions", instructions_json]) | |
print(f"\n--- Running script: {script_path.name} ---") | |
try: | |
# Pass the current environment variables to the subprocess | |
result = subprocess.run(command, check=True, capture_output=True, text=True, env=os.environ) | |
print(result.stdout) | |
if result.stderr: | |
print("Error:") | |
print(result.stderr) | |
except subprocess.CalledProcessError as e: | |
print(f"Error executing {script_path.name}:") | |
print(e.stdout) | |
print(e.stderr) | |
raise # Re-raise the exception to stop the workflow if a script fails | |
def generate_html_for_demo(image_path, instructions): | |
""" | |
A refactored main function for Gradio demo integration. | |
It orchestrates the script executions for a single image processing run. | |
- Creates a unique run_id for each call. | |
- Sets up temporary directories for input and output. | |
- Cleans up temporary directories after execution. | |
""" | |
run_id = str(uuid.uuid4()) | |
print(f"--- Starting Screencoder workflow for run_id: {run_id} ---") | |
# HF Spaces: Use absolute paths and pathlib for robustness | |
base_dir = Path(__file__).parent.resolve() | |
tmp_dir = base_dir / 'data' / 'tmp' / run_id | |
output_dir = base_dir / 'data' / 'output' / run_id | |
os.makedirs(tmp_dir, exist_ok=True) | |
os.makedirs(output_dir, exist_ok=True) | |
try: | |
# 1. Copy user-uploaded image to the temp input directory | |
new_image_path = tmp_dir / f"{run_id}.png" | |
img = Image.open(image_path) | |
img.save(new_image_path, "PNG") | |
# 2. Run the processing scripts in sequence | |
run_script_with_run_id("UIED/run_single.py", run_id) | |
run_script_with_run_id("block_parsor.py", run_id) | |
run_script_with_run_id("html_generator.py", run_id, instructions) | |
run_script_with_run_id("image_box_detection.py", run_id) | |
run_script_with_run_id("mapping.py", run_id) | |
run_script_with_run_id("image_replacer.py", run_id) | |
# 3. Read the final generated HTML | |
final_html_path = output_dir / f"{run_id}_layout_final.html" | |
if final_html_path.exists(): | |
with open(final_html_path, 'r', encoding='utf-8') as f: | |
html_content = f.read() | |
print(f"Successfully generated HTML for run_id: {run_id}") | |
return html_content, run_id | |
else: | |
error_msg = f"Error: Final HTML file not found for run_id: {run_id}" | |
return error_msg, run_id | |
except Exception as e: | |
error_msg = f"An error occurred: {e}" | |
print(f"An error occurred during the workflow for run_id {run_id}: {e}") | |
return error_msg, run_id | |
finally: | |
# 4. Cleanup: Remove temporary directories | |
try: | |
# shutil.rmtree(tmp_dir) | |
# shutil.rmtree(output_dir) | |
print(f"Cleaned up temporary files for run_id: {run_id}") | |
except OSError as e: | |
print(f"Error cleaning up temporary files for run_id {run_id}: {e}") | |
def main(): | |
"""Main function to run the entire Screencoder workflow (legacy).""" | |
print("Starting the Screencoder full workflow (legacy)...") | |
# This main function is now considered legacy and should not be used in HF Spaces. | |
run_id = "test1" # Hardcoded for legacy main | |
# Use a dummy image path for legacy run | |
dummy_image_path = Path(__file__).parent.resolve() / "data" / "input" / "test1.png" | |
instructions = {"main content": "Generate the HTML for this screenshot."} | |
generate_html_for_demo(str(dummy_image_path), instructions) | |
print("\nScreencoder workflow completed successfully!") | |
if __name__ == "__main__": | |
main() |