Spaces:
Sleeping
Sleeping
import streamlit as st | |
import ast | |
import base64 | |
import streamlit.components.v1 as components | |
from transformers import pipeline | |
from gtts import gTTS | |
st.set_page_config(page_title="AR/VR Code Visualizer", layout="wide") | |
st.title("π AR/VR Code Visualizer with Call Relationships + Narration") | |
def load_model(): | |
return pipeline("summarization", model="philschmid/bart-large-cnn-samsum") | |
summarizer = load_model() | |
uploaded_file = st.file_uploader("π Upload a Python file", type=["py"]) | |
if uploaded_file: | |
code = uploaded_file.read().decode("utf-8") | |
st.code(code, language="python") | |
# Parse AST for functions and call relationships | |
tree = ast.parse(code) | |
class FunctionCallVisitor(ast.NodeVisitor): | |
def __init__(self): | |
self.calls = {} | |
def visit_FunctionDef(self, node): | |
caller = node.name | |
self.calls[caller] = [] | |
for child in ast.walk(node): | |
if isinstance(child, ast.Call) and isinstance(child.func, ast.Name): | |
self.calls[caller].append(child.func.id) | |
self.generic_visit(node) | |
visitor = FunctionCallVisitor() | |
visitor.visit(tree) | |
call_graph = visitor.calls | |
all_functions = list(call_graph.keys()) | |
# Show call relationships | |
st.subheader("π Call Relationships") | |
for fn, callees in call_graph.items(): | |
st.write(f"πΉ `{fn}` calls: {', '.join(callees) if callees else 'None'}") | |
# Hugging Face summarization | |
prompt = f"Explain the structure and purpose of the following functions and how they call each other: {call_graph}" | |
summary = summarizer(prompt, max_length=60, min_length=15, do_sample=False) | |
summary_text = summary[0]['summary_text'] | |
st.success(summary_text) | |
# Voice narration | |
st.subheader("π Voice Narration of Code Summary") | |
tts = gTTS(text=summary_text) | |
tts.save("summary.mp3") | |
audio_file = open("summary.mp3", "rb") | |
st.audio(audio_file.read(), format="audio/mp3") | |
# Generate A-Frame scene | |
def generate_aframe(call_graph): | |
spacing = 3 | |
boxes = [] | |
lines = [] | |
positions = {} | |
for i, fn in enumerate(call_graph): | |
x = i * spacing | |
positions[fn] = (x, 1, -3) | |
boxes.append(f''' | |
<a-box position="{x} 1 -3" depth="0.5" height="0.5" width="2" color="#FFC65D"></a-box> | |
<a-text value="{fn}" position="{x} 1.8 -3" align="center" color="#000"></a-text> | |
''') | |
for caller, callees in call_graph.items(): | |
for callee in callees: | |
if callee in positions: | |
x1, y1, z1 = positions[caller] | |
x2, y2, z2 = positions[callee] | |
lines.append(f''' | |
<a-entity line="start: {x1} {y1} {z1}; end: {x2} {y2} {z2}; color: red"></a-entity> | |
''') | |
html = f''' | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script> | |
</head> | |
<body> | |
<a-scene background="color: #ECECEC"> | |
<a-entity position="0 1.6 3"> | |
<a-camera wasd-controls-enabled="true" look-controls-enabled="true"></a-camera> | |
</a-entity> | |
<a-light type="ambient" color="#FFF"></a-light> | |
<a-plane rotation="-90 0 0" width="40" height="40" color="#7BC8A4"></a-plane> | |
{''.join(boxes)} | |
{''.join(lines)} | |
</a-scene> | |
</body> | |
</html> | |
''' | |
return html | |
aframe_html = generate_aframe(call_graph) | |
b64 = base64.b64encode(aframe_html.encode()).decode() | |
data_url = f"data:text/html;base64,{b64}" | |
st.subheader("π 3D Call Relationship Visualization") | |
components.iframe(data_url, height=500) | |
else: | |
st.info("Upload a Python file to visualize its structure, relationships, and get narrated summary.") | |