Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -5,9 +5,10 @@ import streamlit.components.v1 as components
|
|
5 |
from transformers import pipeline
|
6 |
from gtts import gTTS
|
7 |
import os
|
8 |
-
import qrcode
|
|
|
9 |
|
10 |
-
#
|
11 |
st.set_page_config(page_title="AR/VR Code Visualizer", layout="wide")
|
12 |
st.title("π AR/VR Code Visualizer with Editing, Interaction, and Export")
|
13 |
|
@@ -17,14 +18,14 @@ def load_model():
|
|
17 |
|
18 |
summarizer = load_model()
|
19 |
|
20 |
-
#
|
21 |
st.subheader("π Write or Paste Your Python Code")
|
22 |
code = st.text_area("Enter your Python code here", height=300)
|
23 |
|
24 |
if code.strip():
|
25 |
st.code(code, language="python")
|
26 |
|
27 |
-
# Parse
|
28 |
tree = ast.parse(code)
|
29 |
|
30 |
class FunctionCallVisitor(ast.NodeVisitor):
|
@@ -42,27 +43,26 @@ if code.strip():
|
|
42 |
visitor = FunctionCallVisitor()
|
43 |
visitor.visit(tree)
|
44 |
call_graph = visitor.calls
|
45 |
-
all_functions = list(call_graph.keys())
|
46 |
|
|
|
47 |
st.subheader("π Function Calls")
|
48 |
for fn, callees in call_graph.items():
|
49 |
st.write(f"πΉ `{fn}` calls: {', '.join(callees) if callees else 'None'}")
|
50 |
|
51 |
-
# Generate AI
|
52 |
prompt = f"Explain the structure and purpose of the following functions and how they call each other: {call_graph}"
|
53 |
summary = summarizer(prompt, max_length=60, min_length=15, do_sample=False)
|
54 |
summary_text = summary[0]['summary_text']
|
55 |
st.success(summary_text)
|
56 |
|
57 |
-
#
|
58 |
st.subheader("π Voice Narration")
|
59 |
tts = gTTS(text=summary_text)
|
60 |
tts.save("summary.mp3")
|
61 |
st.audio("summary.mp3", format="audio/mp3")
|
62 |
|
63 |
-
# A-Frame
|
64 |
def generate_aframe(call_graph):
|
65 |
-
# Serialize function data to JSON format
|
66 |
function_data = {
|
67 |
"functions": [],
|
68 |
"relationships": []
|
@@ -70,12 +70,10 @@ if code.strip():
|
|
70 |
|
71 |
function_positions = {}
|
72 |
spacing = 3
|
73 |
-
i
|
74 |
-
for fn in call_graph:
|
75 |
x = i * spacing
|
76 |
function_positions[fn] = (x, 1, -3)
|
77 |
function_data["functions"].append({"name": fn, "position": [x, 1, -3]})
|
78 |
-
i += 1
|
79 |
|
80 |
for caller, callees in call_graph.items():
|
81 |
for callee in callees:
|
@@ -84,13 +82,10 @@ if code.strip():
|
|
84 |
x2, y2, z2 = function_positions[callee]
|
85 |
function_data["relationships"].append({"start": [x1, y1, z1], "end": [x2, y2, z2]})
|
86 |
|
87 |
-
# JavaScript to render the function data dynamically using JSON
|
88 |
js = """
|
89 |
<script>
|
90 |
-
// The JSON data will be passed as a global variable
|
91 |
const functionData = """ + str(function_data).replace("'", '"') + """;
|
92 |
-
|
93 |
-
// Render boxes dynamically based on function data
|
94 |
functionData.functions.forEach(function(fn) {
|
95 |
const el = document.createElement('a-box');
|
96 |
el.setAttribute('id', fn.name);
|
@@ -105,7 +100,6 @@ if code.strip():
|
|
105 |
el.setAttribute('onclick', `say('${fn.name}')`);
|
106 |
document.querySelector('a-scene').appendChild(el);
|
107 |
|
108 |
-
// Add text for the function
|
109 |
const text = document.createElement('a-text');
|
110 |
text.setAttribute('value', fn.name);
|
111 |
text.setAttribute('position', `${fn.position[0]} ${fn.position[1] + 1} ${fn.position[2]}`);
|
@@ -114,14 +108,12 @@ if code.strip():
|
|
114 |
document.querySelector('a-scene').appendChild(text);
|
115 |
});
|
116 |
|
117 |
-
// Render relationship lines dynamically based on function data
|
118 |
functionData.relationships.forEach(function(rel) {
|
119 |
const el = document.createElement('a-entity');
|
120 |
el.setAttribute('line', `start: ${rel.start.join(' ')}; end: ${rel.end.join(' ')}; color: red`);
|
121 |
document.querySelector('a-scene').appendChild(el);
|
122 |
});
|
123 |
-
|
124 |
-
// Text-to-speech function for box click
|
125 |
function say(text) {
|
126 |
const utter = new SpeechSynthesisUtterance(text);
|
127 |
speechSynthesis.speak(utter);
|
@@ -129,7 +121,6 @@ if code.strip():
|
|
129 |
</script>
|
130 |
"""
|
131 |
|
132 |
-
# HTML structure for A-Frame scene
|
133 |
html = f"""
|
134 |
<!DOCTYPE html>
|
135 |
<html>
|
@@ -159,19 +150,23 @@ if code.strip():
|
|
159 |
st.subheader("π Interactive 3D Function Visualizer")
|
160 |
components.iframe(data_url, height=600)
|
161 |
|
162 |
-
# QR
|
|
|
163 |
qr = qrcode.QRCode(
|
164 |
version=1,
|
165 |
error_correction=qrcode.constants.ERROR_CORRECT_L,
|
166 |
box_size=10,
|
167 |
border=4,
|
168 |
)
|
169 |
-
|
170 |
-
|
|
|
171 |
qr.make(fit=True)
|
172 |
|
173 |
-
# Create and display the QR Code
|
174 |
img = qr.make_image(fill='black', back_color='white')
|
175 |
-
|
|
|
|
|
|
|
176 |
else:
|
177 |
-
st.info("Write some Python code above to visualize, narrate, and explore it in
|
|
|
5 |
from transformers import pipeline
|
6 |
from gtts import gTTS
|
7 |
import os
|
8 |
+
import qrcode
|
9 |
+
from io import BytesIO
|
10 |
|
11 |
+
# Page config
|
12 |
st.set_page_config(page_title="AR/VR Code Visualizer", layout="wide")
|
13 |
st.title("π AR/VR Code Visualizer with Editing, Interaction, and Export")
|
14 |
|
|
|
18 |
|
19 |
summarizer = load_model()
|
20 |
|
21 |
+
# Code input area
|
22 |
st.subheader("π Write or Paste Your Python Code")
|
23 |
code = st.text_area("Enter your Python code here", height=300)
|
24 |
|
25 |
if code.strip():
|
26 |
st.code(code, language="python")
|
27 |
|
28 |
+
# Parse code to extract functions and their calls
|
29 |
tree = ast.parse(code)
|
30 |
|
31 |
class FunctionCallVisitor(ast.NodeVisitor):
|
|
|
43 |
visitor = FunctionCallVisitor()
|
44 |
visitor.visit(tree)
|
45 |
call_graph = visitor.calls
|
|
|
46 |
|
47 |
+
# Display call relationships
|
48 |
st.subheader("π Function Calls")
|
49 |
for fn, callees in call_graph.items():
|
50 |
st.write(f"πΉ `{fn}` calls: {', '.join(callees) if callees else 'None'}")
|
51 |
|
52 |
+
# Generate AI Summary
|
53 |
prompt = f"Explain the structure and purpose of the following functions and how they call each other: {call_graph}"
|
54 |
summary = summarizer(prompt, max_length=60, min_length=15, do_sample=False)
|
55 |
summary_text = summary[0]['summary_text']
|
56 |
st.success(summary_text)
|
57 |
|
58 |
+
# Voice narration using gTTS
|
59 |
st.subheader("π Voice Narration")
|
60 |
tts = gTTS(text=summary_text)
|
61 |
tts.save("summary.mp3")
|
62 |
st.audio("summary.mp3", format="audio/mp3")
|
63 |
|
64 |
+
# Generate A-Frame HTML scene
|
65 |
def generate_aframe(call_graph):
|
|
|
66 |
function_data = {
|
67 |
"functions": [],
|
68 |
"relationships": []
|
|
|
70 |
|
71 |
function_positions = {}
|
72 |
spacing = 3
|
73 |
+
for i, fn in enumerate(call_graph):
|
|
|
74 |
x = i * spacing
|
75 |
function_positions[fn] = (x, 1, -3)
|
76 |
function_data["functions"].append({"name": fn, "position": [x, 1, -3]})
|
|
|
77 |
|
78 |
for caller, callees in call_graph.items():
|
79 |
for callee in callees:
|
|
|
82 |
x2, y2, z2 = function_positions[callee]
|
83 |
function_data["relationships"].append({"start": [x1, y1, z1], "end": [x2, y2, z2]})
|
84 |
|
|
|
85 |
js = """
|
86 |
<script>
|
|
|
87 |
const functionData = """ + str(function_data).replace("'", '"') + """;
|
88 |
+
|
|
|
89 |
functionData.functions.forEach(function(fn) {
|
90 |
const el = document.createElement('a-box');
|
91 |
el.setAttribute('id', fn.name);
|
|
|
100 |
el.setAttribute('onclick', `say('${fn.name}')`);
|
101 |
document.querySelector('a-scene').appendChild(el);
|
102 |
|
|
|
103 |
const text = document.createElement('a-text');
|
104 |
text.setAttribute('value', fn.name);
|
105 |
text.setAttribute('position', `${fn.position[0]} ${fn.position[1] + 1} ${fn.position[2]}`);
|
|
|
108 |
document.querySelector('a-scene').appendChild(text);
|
109 |
});
|
110 |
|
|
|
111 |
functionData.relationships.forEach(function(rel) {
|
112 |
const el = document.createElement('a-entity');
|
113 |
el.setAttribute('line', `start: ${rel.start.join(' ')}; end: ${rel.end.join(' ')}; color: red`);
|
114 |
document.querySelector('a-scene').appendChild(el);
|
115 |
});
|
116 |
+
|
|
|
117 |
function say(text) {
|
118 |
const utter = new SpeechSynthesisUtterance(text);
|
119 |
speechSynthesis.speak(utter);
|
|
|
121 |
</script>
|
122 |
"""
|
123 |
|
|
|
124 |
html = f"""
|
125 |
<!DOCTYPE html>
|
126 |
<html>
|
|
|
150 |
st.subheader("π Interactive 3D Function Visualizer")
|
151 |
components.iframe(data_url, height=600)
|
152 |
|
153 |
+
# Generate and display QR code for AR/VR view
|
154 |
+
st.subheader("π± AR View on Mobile")
|
155 |
qr = qrcode.QRCode(
|
156 |
version=1,
|
157 |
error_correction=qrcode.constants.ERROR_CORRECT_L,
|
158 |
box_size=10,
|
159 |
border=4,
|
160 |
)
|
161 |
+
|
162 |
+
space_url = "https://huggingface.co/spaces/your-space-name" # Replace with actual Hugging Face Space URL
|
163 |
+
qr.add_data(space_url)
|
164 |
qr.make(fit=True)
|
165 |
|
|
|
166 |
img = qr.make_image(fill='black', back_color='white')
|
167 |
+
img_byte_arr = BytesIO()
|
168 |
+
img.save(img_byte_arr, format='PNG')
|
169 |
+
img_bytes = img_byte_arr.getvalue()
|
170 |
+
st.image(img_bytes, caption="Scan this QR code to view the VR scene in AR on your mobile!")
|
171 |
else:
|
172 |
+
st.info("Write some Python code above to visualize, narrate, and explore it in 3D/AR.")
|