Srevarshan1502 commited on
Commit
4dbcf14
·
1 Parent(s): a85d4b0

added index.html

Browse files
Files changed (1) hide show
  1. index.html +243 -0
index.html ADDED
@@ -0,0 +1,243 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Interactive Python Executor</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet">
9
+ <style>
10
+ body {
11
+ font-family: 'Inter', sans-serif;
12
+ background-color: #1a202c; /* Dark background */
13
+ color: #e2e8f0; /* Light text */
14
+ display: flex;
15
+ justify-content: center;
16
+ align-items: flex-start;
17
+ min-height: 100vh;
18
+ padding: 2rem;
19
+ box-sizing: border-box;
20
+ }
21
+ .container {
22
+ background-color: #2d3748; /* Slightly lighter dark for container */
23
+ border-radius: 0.75rem; /* rounded-xl */
24
+ box-shadow: 0 10px 15px rgba(0, 0, 0, 0.2); /* shadow-xl */
25
+ padding: 2rem;
26
+ max-width: 900px;
27
+ width: 100%;
28
+ display: flex;
29
+ flex-direction: column;
30
+ gap: 1.5rem;
31
+ }
32
+ textarea, input[type="text"] {
33
+ background-color: #1a202c; /* Even darker for input fields */
34
+ color: #e2e8f0;
35
+ border: 1px solid #4a5568; /* border-gray-600 */
36
+ border-radius: 0.5rem; /* rounded-lg */
37
+ padding: 0.75rem 1rem;
38
+ font-family: 'Fira Code', 'Cascadia Code', 'Consolas', monospace; /* Monospace for code */
39
+ font-size: 0.9rem;
40
+ resize: vertical;
41
+ }
42
+ button {
43
+ padding: 0.75rem 1.5rem;
44
+ border-radius: 0.5rem; /* rounded-lg */
45
+ font-weight: 600; /* font-semibold */
46
+ transition: background-color 0.2s, transform 0.1s;
47
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
48
+ }
49
+ button:hover {
50
+ transform: translateY(-1px);
51
+ }
52
+ .btn-primary {
53
+ background-color: #4299e1; /* blue-500 */
54
+ color: white;
55
+ }
56
+ .btn-primary:hover {
57
+ background-color: #3182ce; /* blue-600 */
58
+ }
59
+ .btn-secondary {
60
+ background-color: #a0aec0; /* gray-400 */
61
+ color: #2d3748;
62
+ }
63
+ .btn-secondary:hover {
64
+ background-color: #718096; /* gray-500 */
65
+ }
66
+ .terminal-output {
67
+ background-color: #000; /* Black for terminal */
68
+ color: #0f0; /* Green text for terminal */
69
+ border-radius: 0.5rem;
70
+ padding: 1rem;
71
+ min-height: 200px;
72
+ max-height: 400px;
73
+ overflow-y: auto;
74
+ white-space: pre-wrap; /* Preserve whitespace and wrap text */
75
+ font-family: 'Fira Code', 'Cascadia Code', 'Consolas', monospace;
76
+ font-size: 0.85rem;
77
+ border: 1px solid #4a5568;
78
+ }
79
+ .input-area {
80
+ display: flex;
81
+ gap: 0.5rem;
82
+ margin-top: 1rem;
83
+ }
84
+ .hidden {
85
+ display: none;
86
+ }
87
+ .status-message {
88
+ font-size: 0.8rem;
89
+ color: #cbd5e0;
90
+ margin-top: 0.5rem;
91
+ }
92
+ </style>
93
+ </head>
94
+ <body class="antialiased">
95
+ <div class="container">
96
+ <h1 class="text-3xl font-bold text-center mb-4 text-blue-300">Interactive Python Interpreter</h1>
97
+ <p class="text-center text-gray-400 mb-6">Enter Python code and interact with it in real-time.</p>
98
+
99
+ <div class="flex flex-col gap-4">
100
+ <label for="code-input" class="text-lg font-semibold text-gray-200">Python Code:</label>
101
+ <textarea id="code-input" rows="15" class="focus:ring-blue-500 focus:border-blue-500">
102
+ # Example: Interactive input
103
+ n = int(input("Enter a number: "))
104
+ if n % 2 == 0:
105
+ print("Even")
106
+ else:
107
+ print("Odd")
108
+
109
+ # Example: Multiple inputs
110
+ name = input("What is your name? ")
111
+ age = int(input("How old are you? "))
112
+ print(f"Hello, {name}! You are {age} years old.")
113
+ </textarea>
114
+ <button id="run-button" class="btn-primary">Run Code</button>
115
+ </div>
116
+
117
+ <div class="flex flex-col gap-4">
118
+ <label for="terminal-output" class="text-lg font-semibold text-gray-200">Terminal Output:</label>
119
+ <div id="terminal-output" class="terminal-output"></div>
120
+ <div id="input-prompt-area" class="input-area hidden">
121
+ <input type="text" id="user-input" class="flex-grow" placeholder="Enter input here...">
122
+ <button id="send-input-button" class="btn-primary">Send Input</button>
123
+ </div>
124
+ <p id="status-message" class="status-message">Status: Not connected</p>
125
+ </div>
126
+ </div>
127
+
128
+ <script>
129
+ const codeInput = document.getElementById('code-input');
130
+ const runButton = document.getElementById('run-button');
131
+ const terminalOutput = document.getElementById('terminal-output');
132
+ const inputPromptArea = document.getElementById('input-prompt-area');
133
+ const userInput = document.getElementById('user-input');
134
+ const sendInputButton = document.getElementById('send-input-button');
135
+ const statusMessage = document.getElementById('status-message');
136
+
137
+ let ws;
138
+ let isAwaitingInput = false;
139
+
140
+ function connectWebSocket() {
141
+ let wsUrl;
142
+ if (window.location.protocol === 'https:') {
143
+ // For Hugging Face Spaces, always use wss:// when the page is loaded over HTTPS
144
+ // window.location.hostname is safer as it never includes the port
145
+ wsUrl = `wss://${window.location.hostname}/ws`;
146
+ } else {
147
+ // For local development (http://localhost:7860)
148
+ wsUrl = `ws://${window.location.host}/ws`;
149
+ }
150
+
151
+ console.log('Attempting to connect WebSocket to:', wsUrl);
152
+ console.log('Current page protocol:', window.location.protocol);
153
+ console.log('Current page hostname:', window.location.hostname);
154
+ console.log('Current page host (includes port):', window.location.host);
155
+
156
+
157
+ ws = new WebSocket(wsUrl);
158
+
159
+ ws.onopen = () => {
160
+ statusMessage.textContent = 'Status: Connected';
161
+ runButton.disabled = false;
162
+ console.log('WebSocket connected');
163
+ };
164
+
165
+ ws.onmessage = (event) => {
166
+ const data = JSON.parse(event.data);
167
+ if (data.type === 'output') {
168
+ terminalOutput.textContent += data.content;
169
+ terminalOutput.scrollTop = terminalOutput.scrollHeight; // Auto-scroll
170
+ } else if (data.type === 'input_request') {
171
+ isAwaitingInput = true;
172
+ inputPromptArea.classList.remove('hidden');
173
+ userInput.focus();
174
+ terminalOutput.scrollTop = terminalOutput.scrollHeight; // Auto-scroll
175
+ } else if (data.type === 'execution_complete') {
176
+ isAwaitingInput = false;
177
+ inputPromptArea.classList.add('hidden');
178
+ userInput.value = '';
179
+ statusMessage.textContent = 'Status: Execution complete.';
180
+ console.log('Execution complete:', data.result);
181
+ } else if (data.type === 'pong') {
182
+ // console.log('Pong received');
183
+ }
184
+ };
185
+
186
+ ws.onclose = (event) => {
187
+ statusMessage.textContent = `Status: Disconnected (Code: ${event.code}, Reason: ${event.reason})`;
188
+ runButton.disabled = true;
189
+ inputPromptArea.classList.add('hidden');
190
+ console.log('WebSocket disconnected:', event);
191
+ // Attempt to reconnect after a delay
192
+ setTimeout(connectWebSocket, 3000);
193
+ };
194
+
195
+ ws.onerror = (error) => {
196
+ statusMessage.textContent = 'Status: Connection error';
197
+ console.error('WebSocket error:', error);
198
+ };
199
+ }
200
+
201
+ runButton.addEventListener('click', () => {
202
+ if (ws && ws.readyState === WebSocket.OPEN) {
203
+ terminalOutput.textContent = ''; // Clear previous output
204
+ statusMessage.textContent = 'Status: Running code...';
205
+ isAwaitingInput = false;
206
+ inputPromptArea.classList.add('hidden'); // Hide input area initially
207
+ userInput.value = ''; // Clear input field
208
+
209
+ const code = codeInput.value;
210
+ ws.send(JSON.stringify({ type: 'code', content: code }));
211
+ } else {
212
+ statusMessage.textContent = 'Status: Not connected. Please wait or refresh.';
213
+ }
214
+ });
215
+
216
+ sendInputButton.addEventListener('click', () => {
217
+ if (isAwaitingInput && ws && ws.readyState === WebSocket.OPEN) {
218
+ const inputContent = userInput.value;
219
+ ws.send(JSON.stringify({ type: 'input', content: inputContent }));
220
+ userInput.value = ''; // Clear input field after sending
221
+ inputPromptArea.classList.add('hidden'); // Hide input area until next prompt
222
+ isAwaitingInput = false;
223
+ }
224
+ });
225
+
226
+ userInput.addEventListener('keypress', (event) => {
227
+ if (event.key === 'Enter') {
228
+ sendInputButton.click();
229
+ }
230
+ });
231
+
232
+ // Start WebSocket connection when the page loads
233
+ document.addEventListener('DOMContentLoaded', connectWebSocket);
234
+
235
+ // Optional: Send a ping every 30 seconds to keep the WebSocket connection alive
236
+ setInterval(() => {
237
+ if (ws && ws.readyState === WebSocket.OPEN) {
238
+ ws.send(JSON.stringify({ type: 'ping' }));
239
+ }
240
+ }, 30000); // 30 seconds
241
+ </script>
242
+ </body>
243
+ </html>