Add code editor with that executes script on isolator
This commit is contained in:
62
app.py
62
app.py
@@ -1,33 +1,69 @@
|
|||||||
import os
|
import os
|
||||||
from flask import Flask, render_template
|
from flask import Flask, Response, jsonify, render_template, request
|
||||||
import jinja_partials
|
import jinja_partials
|
||||||
from jinja2_fragments import render_block
|
from jinja2_fragments import render_block
|
||||||
from flask_htmx import HTMX
|
from flask_htmx import HTMX
|
||||||
import minify_html
|
import minify_html
|
||||||
|
import requests
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.config.from_pyfile('config.py')
|
app.config.from_pyfile('config.py')
|
||||||
jinja_partials.register_extensions(app)
|
jinja_partials.register_extensions(app)
|
||||||
htmx = HTMX(app)
|
htmx = HTMX(app)
|
||||||
|
|
||||||
@app.after_request
|
API_URL = 'https://isolator.peterstockings.com/execute'
|
||||||
def response_minify(response):
|
|
||||||
"""
|
def map_isolator_response_to_flask_response(response):
|
||||||
minify html response to decrease site traffic
|
"""
|
||||||
"""
|
Maps a Node.js response to a Flask response.
|
||||||
if response.content_type == u'text/html; charset=utf-8':
|
|
||||||
response.set_data(
|
:param nodejs_response: The response from Node.js, expected to be a dictionary
|
||||||
minify_html.minify(response.get_data(
|
with keys 'body', 'headers', and 'status'.
|
||||||
as_text=True), minify_js=True, remove_processing_instructions=True)
|
:return: Flask Response object
|
||||||
)
|
"""
|
||||||
|
result = response.get('result', {})
|
||||||
|
body = result.get('body', '')
|
||||||
|
headers = result.get('headers', {})
|
||||||
|
status = result.get('status', 200)
|
||||||
|
|
||||||
|
|
||||||
|
# Convert body to JSON if it's a dictionary
|
||||||
|
body = str(body)
|
||||||
|
|
||||||
|
return Response(response=body, status=status, headers=headers)
|
||||||
|
|
||||||
return response
|
|
||||||
return response
|
|
||||||
|
|
||||||
@ app.route("/", methods=["GET"])
|
@ app.route("/", methods=["GET"])
|
||||||
def index():
|
def index():
|
||||||
return render_template("index.html")
|
return render_template("index.html")
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/execute', methods=['POST'])
|
||||||
|
def execute_code():
|
||||||
|
try:
|
||||||
|
# Extract code and convert request to a format acceptable by Node.js app
|
||||||
|
code = request.json.get('code')
|
||||||
|
request_obj = {
|
||||||
|
'method': request.method,
|
||||||
|
'headers': dict(request.headers),
|
||||||
|
'body': request.json,
|
||||||
|
'url': request.url,
|
||||||
|
# Add other request properties as needed
|
||||||
|
}
|
||||||
|
|
||||||
|
# Call the Node.js API
|
||||||
|
response = requests.post(API_URL, json={'code': code, 'request': request_obj})
|
||||||
|
response_data = response.json()
|
||||||
|
|
||||||
|
# Map the Node.js response to Flask response
|
||||||
|
flask_response = map_isolator_response_to_flask_response(response_data)
|
||||||
|
return flask_response
|
||||||
|
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({'error': str(e)}), 500
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Bind to PORT if defined, otherwise default to 5000.
|
# Bind to PORT if defined, otherwise default to 5000.
|
||||||
port = int(os.environ.get('PORT', 5000))
|
port = int(os.environ.get('PORT', 5000))
|
||||||
|
|||||||
@@ -8,13 +8,88 @@
|
|||||||
<title>Function</title>
|
<title>Function</title>
|
||||||
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700,900&display=swap" rel="stylesheet" />
|
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700,900&display=swap" rel="stylesheet" />
|
||||||
<script src="/static/js/tailwindcss@3.2.4.js"></script>
|
<script src="/static/js/tailwindcss@3.2.4.js"></script>
|
||||||
<script src="/static/js/htmx.min.js" defer></script>
|
<script src="/static/js/htmx.min.js"></script>
|
||||||
<script src="/static/js/hyperscript.min.js" defer></script>
|
<script src="/static/js/hyperscript.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.1/ace.min.js"
|
||||||
|
integrity="sha512-7QPOFYWq4euLbAVbG/o5YVgkotUdMiwFuFrVQc6lbqZuAcWnLp0sQ6JX2AIWqbm3wWrPuEfu9FqckItCgQzBWw=="
|
||||||
|
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.1/mode-javascript.min.js"
|
||||||
|
integrity="sha512-1OTGICMOnGWxRYfDZRUdv7qut0O8+9s7JPi6JNxlz1pdpHgDwPo1L0dzYKwftuIb0ossdBzWtkAlnyyYpIEp2A=="
|
||||||
|
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.1/theme-monokai.min.js"
|
||||||
|
integrity="sha512-g9yptARGYXbHR9r3kTKIAzF+vvmgEieTxuuUUcHC5tKYFpLR3DR+lsisH2KZJG2Nwaou8jjYVRdbbbBQI3Bo5w=="
|
||||||
|
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body class="bg-gray-100 font-roboto">
|
||||||
<h1>Function</h1>
|
<div class="container mx-auto p-4">
|
||||||
<h5>Hello world...</h5>
|
<h1 class="text-4xl font-bold text-gray-800 mb-2">Function</h1>
|
||||||
|
<h5 class="text-xl text-gray-500 mb-4">Create your own javascript HTTP handler</h5>
|
||||||
|
|
||||||
|
<div id="editor" class="relative rounded-lg shadow-lg bg-white p-4 mb-4" style="height: 300px;">async (req) => {
|
||||||
|
console.log('hello world...')
|
||||||
|
return HtmlResponse(`<h1>${req.method}</h1>`)
|
||||||
|
}</div>
|
||||||
|
|
||||||
|
<button id="executeBtn" class="mb-4 bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
|
||||||
|
Execute
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div id="output" class="relative rounded-lg shadow-lg bg-black text-white p-4"
|
||||||
|
style="height: 200px; overflow-y: scroll;">
|
||||||
|
<!-- Execution results will appear here -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var editor = ace.edit("editor");
|
||||||
|
editor.setTheme("ace/theme/monokai");
|
||||||
|
editor.session.setMode("ace/mode/javascript");
|
||||||
|
|
||||||
|
editor.session.$worker.send("changeOptions", [{ asi: true }]);
|
||||||
|
|
||||||
|
|
||||||
|
document.getElementById('executeBtn').addEventListener('click', function () {
|
||||||
|
try {
|
||||||
|
// Get the code from the editor
|
||||||
|
var code = editor.getValue();
|
||||||
|
|
||||||
|
// Define the request object (modify as needed)
|
||||||
|
var requestObject = {
|
||||||
|
// Your request object properties here
|
||||||
|
};
|
||||||
|
|
||||||
|
// Send the code and request object to the server
|
||||||
|
fetch('/execute?playground=true', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ code: code, request: requestObject }),
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(data); // Try to parse the response as JSON
|
||||||
|
// The response was a JSON object
|
||||||
|
document.getElementById('output').textContent = JSON.stringify(data, null, 2);
|
||||||
|
} catch (err) {
|
||||||
|
document.getElementById('output').innerHTML = data;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
document.getElementById('output').textContent = 'Error: ' + error.message;
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
document.getElementById('output').innerHTML = 'Error: ' + e.message;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
Reference in New Issue
Block a user