File size: 1,879 Bytes
392ec35
2b4c887
392ec35
 
ee3d946
 
2b4c887
392ec35
ee3d946
2b4c887
 
 
 
 
392ec35
ee3d946
2b4c887
 
ee3d946
2b4c887
 
 
 
 
ee3d946
2b4c887
 
392ec35
 
ee3d946
 
2b4c887
ee3d946
2b4c887
 
ee3d946
2b4c887
 
ee3d946
2b4c887
ee3d946
2b4c887
 
ee3d946
 
 
 
2b4c887
 
ee3d946
 
 
2b4c887
 
 
 
 
 
 
392ec35
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import gradio as gr
import subprocess
import os

# Use container’s home directory to avoid permission errors
WORKDIR = os.path.join(os.environ['HOME'], "workspace")
os.makedirs(WORKDIR, exist_ok=True)

# HTML iframe to embed noVNC viewer
NO_VNC_IFRAME = """
<iframe src="http://localhost:6080/vnc.html?autoconnect=true&resize=remote"
        style="width:100%; height:600px; border:none;">
</iframe>
"""

def start_desktop():
    return NO_VNC_IFRAME

def run_shell(cmd):
    result = subprocess.run(
        cmd,
        shell=True,
        capture_output=True,
        text=True,
        env={**os.environ, "DISPLAY": ":1"}  # Supports GUI apps if needed
    )
    return result.stdout + result.stderr

def upload_file(file):
    dest_path = os.path.join(WORKDIR, os.path.basename(file.name))
    with open(dest_path, "wb") as f:
        f.write(file.read())
    return f"✅ Uploaded to: {dest_path}"

with gr.Blocks(css="@import url('https://cdn.simplecss.org/simple.min.css');") as demo:
    gr.Markdown("# 🖥️ Offline Visual Sandbox (no API, no cost)")

    with gr.Tab("Desktop"):
        launch_btn = gr.Button("Launch Desktop")
        desktop_view = gr.HTML()
        launch_btn.click(start_desktop, outputs=desktop_view)

    with gr.Tab("Shell"):
        cmd_input = gr.Textbox(label="Shell Command", placeholder="Try 'ls /home/user/workspace'")
        run_btn = gr.Button("Run")
        cmd_output = gr.Textbox(label="Command Output", lines=10)
        run_btn.click(run_shell, inputs=cmd_input, outputs=cmd_output)

    with gr.Tab("Upload"):
        file_input = gr.File(label="Upload File")
        status_output = gr.Textbox(label="Upload Status")
        file_input.change(upload_file, inputs=file_input, outputs=status_output)

    demo.launch(
        server_name="0.0.0.0",
        server_port=7860,
        share=False,
        ssr_mode=False
    )