Spaces:
Running
Running
| import gradio as gr | |
| import html | |
| import io | |
| from contextlib import redirect_stdout | |
| # --- Python runner --- | |
| def run_python(code): | |
| f = io.StringIO() | |
| try: | |
| with redirect_stdout(f): | |
| exec(code, {}, {}) | |
| except Exception as e: | |
| f.write(str(e)) | |
| output = f.getvalue() | |
| return f'<pre style="color:#00ff00; font-family: monospace;">{html.escape(output)}</pre>' | |
| # --- Web runner (working sandbox-safe version) --- | |
| def run_web(code): | |
| # Wrap HTML fragment in full document if needed | |
| if "<html" in code.lower() or "<!doctype" in code.lower(): | |
| html_content = code | |
| else: | |
| html_content = f""" | |
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset='UTF-8'> | |
| <style> | |
| body {{ | |
| font-family: monospace; | |
| background: #1e1e1e; | |
| color: #00ff00; | |
| padding: 20px; | |
| }} | |
| a {{ | |
| color: #00ffff; | |
| }} | |
| img {{ | |
| border-radius: 8px; | |
| margin-top: 10px; | |
| }} | |
| button {{ | |
| background-color: #00ff00; | |
| color: #1e1e1e; | |
| border: none; | |
| border-radius: 4px; | |
| padding: 6px 12px; | |
| cursor: pointer; | |
| margin-top: 10px; | |
| }} | |
| button:hover {{ | |
| background-color: #00cc00; | |
| }} | |
| </style> | |
| </head> | |
| <body> | |
| {code} | |
| </body> | |
| </html> | |
| """ | |
| # Escape quotes for safe embedding | |
| safe_html = html_content.replace('"', """).replace("'", "'") | |
| # Allow interactive content inside iframe safely | |
| return f""" | |
| <iframe | |
| style="width:100%; height:400px; border:none; border-radius:8px; background:#1e1e1e;" | |
| sandbox="allow-scripts allow-same-origin allow-forms allow-popups" | |
| srcdoc="{safe_html}"> | |
| </iframe> | |
| """ | |
| # --- JavaScript runner --- | |
| def run_js(code): | |
| return f'<iframe style="width:100%; height:100%; border:none; border-radius:8px; background:#1e1e1e;" srcdoc="<script>{html.escape(code)}</script>"></iframe>' | |
| # --- Bash runner (simulated) --- | |
| def run_bash(code): | |
| return f'<pre style="color:#00ff00; font-family: monospace;">$ {html.escape(code)}\nCommand simulated.</pre>' | |
| # --- Main runner --- | |
| def run_code(code, lang): | |
| if lang == "Python": | |
| return run_python(code) | |
| elif lang == "JavaScript": | |
| return run_js(code) | |
| elif lang == "Bash": | |
| return run_bash(code) | |
| else: | |
| return run_web(code) | |
| # --- Starter templates --- | |
| starter_python = """# Python example | |
| print("Hello World!") | |
| for i in range(5): | |
| print(f"Line {i+1}")""" | |
| starter_web = """<h1 style="background: linear-gradient(to right, red, orange, yellow, green, blue, indigo, violet); | |
| -webkit-background-clip: text; color: transparent;"> | |
| Hello, Rainbow World! | |
| </h1>""" | |
| starter_js = """// JavaScript example | |
| console.log("Hello JavaScript!"); | |
| for(let i=0;i<5;i++){ | |
| console.log("Line "+(i+1)); | |
| }""" | |
| starter_bash = """# Bash example | |
| echo "Hello Bash!" | |
| for i in {1..5}; do | |
| echo "Line $i" | |
| done""" | |
| # --- Gradio app --- | |
| with gr.Blocks(css=""" | |
| body { | |
| margin:0; padding:0; | |
| font-family:'Poppins', sans-serif; | |
| overflow-x:hidden; | |
| color:#e0e0e0; | |
| background: linear-gradient(to bottom, #0a0a23, #1a0a3a, #00001a); | |
| } | |
| .gradio-container { max-width:1200px; margin:auto; padding:20px; } | |
| .gr-column { display:flex; flex-direction: column; gap:8px !important; } | |
| #editor-container, #output-panel { | |
| width:100% !important; | |
| margin:0 !important; | |
| padding:8px !important; | |
| border-radius:8px; | |
| box-sizing:border-box; | |
| } | |
| #output-panel { | |
| height:150px !important; | |
| background:#1e1e1e; | |
| color:#00ff00; | |
| overflow:auto; | |
| box-shadow:0 4px 8px rgba(0,0,0,0.5); | |
| font-family: monospace; | |
| } | |
| #editor-container .CodeMirror { | |
| height:300px !important; | |
| min-height:300px !important; | |
| font-family: monospace; | |
| font-size:14px; | |
| white-space: pre-wrap; | |
| overflow-wrap: break-word; | |
| border-radius:8px; | |
| padding:8px !important; | |
| } | |
| .gr-radio { color:#e0e0e0; margin:0 0 8px 0 !important; font-size:0.95em; } | |
| button, .gr-button { background-color:#F714C5 !important; color:#fff !important; border-radius:6px !important; padding:8px 16px !important; } | |
| footer { display:none !important; } | |
| header { background:#000000; padding:16px; color:#F714C5; font-size:1.4em; text-align:center; margin-top:20px; } | |
| header img { vertical-align:middle; height:20px; margin-right:8px; } | |
| canvas#particles { position:fixed; top:0; left:0; width:100%; height:100%; z-index:0; pointer-events:none; } | |
| """) as demo: | |
| # --- Particle background --- | |
| gr.HTML("""<canvas id="particles"></canvas> | |
| <script> | |
| const canvas = document.getElementById('particles'); | |
| const ctx = canvas.getContext('2d'); | |
| let stars = []; | |
| function resize(){ canvas.width = window.innerWidth; canvas.height = window.innerHeight; } | |
| window.addEventListener('resize', resize); resize(); | |
| for(let i=0;i<150;i++){ | |
| stars.push({ x: Math.random()*canvas.width, y: Math.random()*canvas.height, | |
| r: Math.random()*1.5, dx: (Math.random()-0.5)*0.3, dy: (Math.random()-0.5)*0.3 }); | |
| } | |
| function animate(){ | |
| ctx.clearRect(0,0,canvas.width,canvas.height); | |
| for(let s of stars){ | |
| ctx.beginPath(); ctx.arc(s.x,s.y,s.r,0,Math.PI*2); ctx.fillStyle='white'; ctx.fill(); | |
| s.x+=s.dx; s.y+=s.dy; | |
| if(s.x<0) s.x=canvas.width; if(s.x>canvas.width) s.x=0; | |
| if(s.y<0) s.y=canvas.height; if(s.y>canvas.height) s.y=0; | |
| } | |
| requestAnimationFrame(animate); | |
| } | |
| animate(); | |
| </script>""") | |
| # --- Header --- | |
| gr.Markdown(""" | |
| <h2 style="color:#F714C5; text-align:center; margin-bottom:10px;"> | |
| πΈ'π ππππ & ππππ ππ ππ’ ππππππππ, πππππ’ ππππππ! | |
| </h2> | |
| """) | |
| # --- Language selector --- | |
| lang_selector = gr.Radio( | |
| choices=["Python", "Web (HTML/CSS/JS)", "JavaScript", "Bash"], | |
| value="Web (HTML/CSS/JS)", | |
| label="Select Language" | |
| ) | |
| # --- Output above input --- | |
| with gr.Column(): | |
| output_frame = gr.HTML(label="Output", elem_id="output-panel") | |
| code_input = gr.Code( | |
| value=starter_web, | |
| language="html", | |
| label="Type your code here", | |
| interactive=True, | |
| lines=15 | |
| ) | |
| render_button = gr.Button("Render") | |
| # --- Footer --- | |
| gr.Markdown(""" | |
| <header> | |
| <img src="https://simpleandstatic.com/favicon.ico" alt="Logo" /> | |
| ππππππ & ππππππ | |
| </header> | |
| """) | |
| # --- Update template on language change --- | |
| def update_template(lang): | |
| if lang == "Python": | |
| return starter_python | |
| elif lang == "JavaScript": | |
| return starter_js | |
| elif lang == "Bash": | |
| return starter_bash | |
| else: | |
| return starter_web | |
| lang_selector.change(update_template, inputs=lang_selector, outputs=code_input) | |
| render_button.click(run_code, inputs=[code_input, lang_selector], outputs=output_frame) | |
| demo.launch() | |