File size: 3,916 Bytes
a794cee
6dea265
5bc4351
382764a
 
 
6407b2f
a794cee
21fe3fa
 
a794cee
21fe3fa
a794cee
382764a
a794cee
382764a
4d30d4b
 
 
 
6dea265
a794cee
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
382764a
6dea265
 
 
 
 
5bc4351
6dea265
5bc4351
 
a794cee
 
 
 
 
 
382764a
a794cee
6dea265
6407b2f
5bc4351
 
 
6dea265
5bc4351
6dea265
21fe3fa
a794cee
 
21fe3fa
6dea265
382764a
 
a794cee
 
 
 
 
 
 
 
382764a
4d30d4b
a794cee
 
6407b2f
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# app.py
from flask import Flask, request, jsonify, render_template, stream_with_context, Response
import os
import subprocess
import tempfile
import shutil
import sys
import logging

app = Flask(__name__)
logging.basicConfig(level=logging.DEBUG)

# Create a temporary directory for operations with full permissions
temp_dir = tempfile.mkdtemp()
os.chmod(temp_dir, 0o777)

@app.route("/")
def index():
    return render_template("index.html")

def execute_shell_command(command):
    """Executes a shell command and streams output with improved error handling."""
    try:
        # Split the command for better security and handling
        if command.startswith('git clone'):
            # Special handling for git clone
            process = subprocess.Popen(
                command,
                shell=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True,
                cwd=temp_dir,
                env={'GIT_TERMINAL_PROMPT': '0'}  # Prevent git from prompting
            )
        else:
            process = subprocess.Popen(
                command,
                shell=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True,
                cwd=temp_dir
            )

        # Stream output in real-time
        while True:
            output = process.stdout.readline()
            error = process.stderr.readline()
            
            if output:
                yield f"{output}<br>"
            if error:
                yield f"<span style='color: red'>Error: {error}</span><br>"
            
            # Check if process has finished
            if output == '' and error == '' and process.poll() is not None:
                break

        # Get return code
        return_code = process.poll()
        if return_code != 0:
            yield f"<span style='color: red'>Command failed with return code {return_code}</span><br>"
        else:
            yield "Command completed successfully.<br>"

    except Exception as e:
        yield f"<span style='color: red'>Error executing command: {str(e)}</span><br>"
    finally:
        if process:
            process.stdout.close()
            process.stderr.close()

@app.route("/execute", methods=["POST"])
def execute_code():
    command = request.json.get("code", "").strip()
    if not command:
        return jsonify({"result": "Error: No command provided."})

    try:
        if command.startswith("!"):
            shell_command = command[1:]
            # Log the command being executed
            app.logger.debug(f"Executing shell command: {shell_command}")
            return Response(
                stream_with_context(execute_shell_command(shell_command)),
                content_type='text/html'
            )
        else:
            # Handle Python code execution
            process = subprocess.run(
                [sys.executable, "-c", command],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True,
                cwd=temp_dir
            )
            return jsonify({"result": process.stdout + process.stderr})
    except Exception as e:
        app.logger.error(f"Error executing command: {str(e)}")
        return jsonify({"result": f"Error: {str(e)}"})

@app.route("/cleanup", methods=["POST"])
def cleanup():
    global temp_dir
    try:
        if os.path.exists(temp_dir):
            shutil.rmtree(temp_dir, ignore_errors=True)
        temp_dir = tempfile.mkdtemp()
        os.chmod(temp_dir, 0o777)
        return jsonify({"result": "Temporary files cleaned up."})
    except Exception as e:
        return jsonify({"result": f"Error during cleanup: {str(e)}"})

if __name__ == "__main__":
    # Ensure the temp directory has proper permissions
    os.chmod(temp_dir, 0o777)
    app.run(host="0.0.0.0", port=7860, debug=True)