masadonline commited on
Commit
be4e070
Β·
verified Β·
1 Parent(s): e1dd757

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +76 -44
app.py CHANGED
@@ -4,9 +4,10 @@ import base64
4
  import streamlit.components.v1 as components
5
  from transformers import pipeline
6
  from gtts import gTTS
 
7
 
8
  st.set_page_config(page_title="AR/VR Code Visualizer", layout="wide")
9
- st.title("πŸ‘“ AR/VR Code Visualizer with Call Relationships + Narration")
10
 
11
  @st.cache_resource
12
  def load_model():
@@ -14,13 +15,14 @@ def load_model():
14
 
15
  summarizer = load_model()
16
 
17
- uploaded_file = st.file_uploader("πŸ“ Upload a Python file", type=["py"])
 
 
18
 
19
- if uploaded_file:
20
- code = uploaded_file.read().decode("utf-8")
21
  st.code(code, language="python")
22
 
23
- # Parse AST for functions and call relationships
24
  tree = ast.parse(code)
25
 
26
  class FunctionCallVisitor(ast.NodeVisitor):
@@ -40,75 +42,105 @@ if uploaded_file:
40
  call_graph = visitor.calls
41
  all_functions = list(call_graph.keys())
42
 
43
- # Show call relationships
44
- st.subheader("πŸ“Š Call Relationships")
45
  for fn, callees in call_graph.items():
46
  st.write(f"πŸ”Ή `{fn}` calls: {', '.join(callees) if callees else 'None'}")
47
 
48
- # Hugging Face summarization
49
  prompt = f"Explain the structure and purpose of the following functions and how they call each other: {call_graph}"
50
  summary = summarizer(prompt, max_length=60, min_length=15, do_sample=False)
51
  summary_text = summary[0]['summary_text']
52
  st.success(summary_text)
53
 
54
- # Voice narration
55
- st.subheader("πŸ”Š Voice Narration of Code Summary")
56
  tts = gTTS(text=summary_text)
57
  tts.save("summary.mp3")
58
- audio_file = open("summary.mp3", "rb")
59
- st.audio(audio_file.read(), format="audio/mp3")
60
 
61
- # Generate A-Frame scene
62
  def generate_aframe(call_graph):
63
  spacing = 3
64
  boxes = []
65
  lines = []
66
- positions = {}
67
 
68
- for i, fn in enumerate(call_graph):
 
 
69
  x = i * spacing
70
- positions[fn] = (x, 1, -3)
71
- boxes.append(f'''
72
- <a-box position="{x} 1 -3" depth="0.5" height="0.5" width="2" color="#FFC65D"></a-box>
73
- <a-text value="{fn}" position="{x} 1.8 -3" align="center" color="#000"></a-text>
74
- ''')
 
 
 
 
 
 
 
75
 
76
  for caller, callees in call_graph.items():
77
  for callee in callees:
78
- if callee in positions:
79
- x1, y1, z1 = positions[caller]
80
- x2, y2, z2 = positions[callee]
81
- lines.append(f'''
82
  <a-entity line="start: {x1} {y1} {z1}; end: {x2} {y2} {z2}; color: red"></a-entity>
83
- ''')
84
-
85
- html = f'''
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  <!DOCTYPE html>
87
  <html>
88
- <head>
89
  <script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script>
90
- </head>
91
- <body>
92
- <a-scene background="color: #ECECEC">
93
- <a-entity position="0 1.6 3">
94
- <a-camera wasd-controls-enabled="true" look-controls-enabled="true"></a-camera>
95
- </a-entity>
96
- <a-light type="ambient" color="#FFF"></a-light>
97
- <a-plane rotation="-90 0 0" width="40" height="40" color="#7BC8A4"></a-plane>
98
- {''.join(boxes)}
99
- {''.join(lines)}
 
 
 
 
100
  </a-scene>
101
- </body>
102
  </html>
103
- '''
104
  return html
105
 
106
  aframe_html = generate_aframe(call_graph)
107
  b64 = base64.b64encode(aframe_html.encode()).decode()
108
  data_url = f"data:text/html;base64,{b64}"
109
 
110
- st.subheader("🌐 3D Call Relationship Visualization")
111
- components.iframe(data_url, height=500)
112
-
113
  else:
114
- st.info("Upload a Python file to visualize its structure, relationships, and get narrated summary.")
 
4
  import streamlit.components.v1 as components
5
  from transformers import pipeline
6
  from gtts import gTTS
7
+ import os
8
 
9
  st.set_page_config(page_title="AR/VR Code Visualizer", layout="wide")
10
+ st.title("πŸ‘“ AR/VR Code Visualizer with Editing, Interaction, and Export")
11
 
12
  @st.cache_resource
13
  def load_model():
 
15
 
16
  summarizer = load_model()
17
 
18
+ # In-browser code editor
19
+ st.subheader("πŸ“ Write or Paste Your Python Code")
20
+ code = st.text_area("Enter your Python code here", height=300)
21
 
22
+ if code.strip():
 
23
  st.code(code, language="python")
24
 
25
+ # Parse AST for functions and calls
26
  tree = ast.parse(code)
27
 
28
  class FunctionCallVisitor(ast.NodeVisitor):
 
42
  call_graph = visitor.calls
43
  all_functions = list(call_graph.keys())
44
 
45
+ st.subheader("πŸ“Š Function Calls")
 
46
  for fn, callees in call_graph.items():
47
  st.write(f"πŸ”Ή `{fn}` calls: {', '.join(callees) if callees else 'None'}")
48
 
49
+ # Generate AI summary
50
  prompt = f"Explain the structure and purpose of the following functions and how they call each other: {call_graph}"
51
  summary = summarizer(prompt, max_length=60, min_length=15, do_sample=False)
52
  summary_text = summary[0]['summary_text']
53
  st.success(summary_text)
54
 
55
+ # Generate voice narration
56
+ st.subheader("πŸ”Š Voice Narration")
57
  tts = gTTS(text=summary_text)
58
  tts.save("summary.mp3")
59
+ st.audio("summary.mp3", format="audio/mp3")
 
60
 
61
+ # A-Frame VR scene with interactivity and export
62
  def generate_aframe(call_graph):
63
  spacing = 3
64
  boxes = []
65
  lines = []
66
+ positions = []
67
 
68
+ function_positions = {}
69
+ i = 0
70
+ for fn in call_graph:
71
  x = i * spacing
72
+ function_positions[fn] = (x, 1, -3)
73
+ positions.append(fn)
74
+ boxes.append(f"""
75
+ <a-box id="{fn}" position="{x} 1 -3" depth="0.5" height="0.5" width="2" color="#FFC65D"
76
+ class="clickable"
77
+ event-set__enter="_event: mouseenter; color: #00CED1"
78
+ event-set__leave="_event: mouseleave; color: #FFC65D"
79
+ onclick="say('{fn}')">
80
+ </a-box>
81
+ <a-text value="{fn}" position="{x} 2 -3" align="center" color="#000"></a-text>
82
+ """)
83
+ i += 1
84
 
85
  for caller, callees in call_graph.items():
86
  for callee in callees:
87
+ if callee in function_positions:
88
+ x1, y1, z1 = function_positions[caller]
89
+ x2, y2, z2 = function_positions[callee]
90
+ lines.append(f"""
91
  <a-entity line="start: {x1} {y1} {z1}; end: {x2} {y2} {z2}; color: red"></a-entity>
92
+ """)
93
+
94
+ # JavaScript for text-to-speech on click + screenshot
95
+ js = """
96
+ <script>
97
+ function say(text) {
98
+ const utter = new SpeechSynthesisUtterance(text);
99
+ speechSynthesis.speak(utter);
100
+ }
101
+ function downloadScreenshot() {
102
+ const scene = document.querySelector('a-scene');
103
+ scene.components.screenshot.capture('perspective');
104
+ setTimeout(() => {
105
+ const a = document.createElement('a');
106
+ a.href = scene.components.screenshot.canvas.toDataURL();
107
+ a.download = 'scene.png';
108
+ a.click();
109
+ }, 500);
110
+ }
111
+ </script>
112
+ """
113
+
114
+ html = f"""
115
  <!DOCTYPE html>
116
  <html>
117
+ <head>
118
  <script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script>
119
+ <script src="https://cdn.jsdelivr.net/gh/donmccurdy/[email protected]/dist/aframe-extras.min.js"></script>
120
+ <script src="https://unpkg.com/[email protected]/dist/aframe-screenshot-component.min.js"></script>
121
+ {js}
122
+ </head>
123
+ <body>
124
+ <button onclick="downloadScreenshot()" style="position: absolute; z-index: 9999; top: 10px; left: 10px; font-size: 16px;">πŸ“Έ Download Screenshot</button>
125
+ <a-scene screenshot>
126
+ <a-entity position="0 1.6 3">
127
+ <a-camera wasd-controls-enabled="true" look-controls-enabled="true"></a-camera>
128
+ </a-entity>
129
+ <a-light type="ambient" color="#FFF"></a-light>
130
+ <a-plane rotation="-90 0 0" width="40" height="40" color="#7BC8A4"></a-plane>
131
+ {''.join(boxes)}
132
+ {''.join(lines)}
133
  </a-scene>
134
+ </body>
135
  </html>
136
+ """
137
  return html
138
 
139
  aframe_html = generate_aframe(call_graph)
140
  b64 = base64.b64encode(aframe_html.encode()).decode()
141
  data_url = f"data:text/html;base64,{b64}"
142
 
143
+ st.subheader("🌐 Interactive 3D Function Visualizer")
144
+ components.iframe(data_url, height=600)
 
145
  else:
146
+ st.info("Write some Python code above to visualize, narrate, and explore it in VR.")