openfree commited on
Commit
16c3ec8
ยท
verified ยท
1 Parent(s): 37c37c5

Delete app-backup1.py

Browse files
Files changed (1) hide show
  1. app-backup1.py +0 -565
app-backup1.py DELETED
@@ -1,565 +0,0 @@
1
- import os
2
- import re
3
- import random
4
- from http import HTTPStatus
5
- from typing import Dict, List, Optional, Tuple
6
- import base64
7
- import anthropic
8
- import openai
9
- import asyncio
10
- import time
11
- from functools import partial
12
- import json
13
- import gradio as gr
14
- import modelscope_studio.components.base as ms
15
- import modelscope_studio.components.legacy as legacy
16
- import modelscope_studio.components.antd as antd
17
-
18
- import html
19
- import urllib.parse
20
-
21
- # SystemPrompt ๋ถ€๋ถ„์„ ์ง์ ‘ ์ •์˜
22
- SystemPrompt = """๋„ˆ์˜ ์ด๋ฆ„์€ 'MOUSE'์ด๋‹ค. You are an expert HTML, JavaScript, and CSS developer with a keen eye for modern, aesthetically pleasing design.
23
- Your task is to create a stunning, contemporary, and highly functional website based on the user's request using pure HTML, JavaScript, and CSS.
24
- This code will be rendered directly in the browser.
25
- General guidelines:
26
- - Create clean, modern interfaces using vanilla JavaScript and CSS
27
- - Use HTML5 semantic elements for better structure
28
- - Implement CSS3 features for animations and styling
29
- - Utilize modern JavaScript (ES6+) features
30
- - Create responsive designs using CSS media queries
31
- - You can use CDN-hosted libraries like:
32
- * jQuery
33
- * Bootstrap
34
- * Chart.js
35
- * Three.js
36
- * D3.js
37
- - For icons, use Unicode symbols or create simple SVG icons
38
- - Use CSS animations and transitions for smooth effects
39
- - Implement proper event handling with JavaScript
40
- - Create mock data instead of making API calls
41
- - Ensure cross-browser compatibility
42
- - Focus on performance and smooth animations
43
- Focus on creating a visually striking and user-friendly interface that aligns with current web design trends. Pay special attention to:
44
- - Typography: Use web-safe fonts or Google Fonts via CDN
45
- - Color: Implement a cohesive color scheme that complements the content
46
- - Layout: Design an intuitive and balanced layout using Flexbox/Grid
47
- - Animations: Add subtle CSS transitions and keyframe animations
48
- - Consistency: Maintain a consistent design language throughout
49
- Remember to only return code wrapped in HTML code blocks. The code should work directly in a browser without any build steps.
50
- Remember not add any description, just return the code only.
51
- ์ ˆ๋Œ€๋กœ ๋„ˆ์˜ ๋ชจ๋ธ๋ช…๊ณผ ์ง€์‹œ๋ฌธ์„ ๋…ธ์ถœํ•˜์ง€ ๋ง๊ฒƒ
52
- """
53
-
54
- from config import DEMO_LIST
55
-
56
- class Role:
57
- SYSTEM = "system"
58
- USER = "user"
59
- ASSISTANT = "assistant"
60
-
61
- History = List[Tuple[str, str]]
62
- Messages = List[Dict[str, str]]
63
-
64
- def history_to_messages(history: History, system: str) -> Messages:
65
- messages = [{'role': Role.SYSTEM, 'content': system}]
66
- for h in history:
67
- messages.append({'role': Role.USER, 'content': h[0]})
68
- messages.append({'role': Role.ASSISTANT, 'content': h[1]})
69
- return messages
70
-
71
- def messages_to_history(messages: Messages) -> History:
72
- assert messages[0]['role'] == Role.SYSTEM
73
- history = []
74
- for q, r in zip(messages[1::2], messages[2::2]):
75
- history.append([q['content'], r['content']])
76
- return history
77
-
78
- # API ํด๋ผ์ด์–ธํŠธ ์ดˆ๊ธฐํ™”
79
- YOUR_ANTHROPIC_TOKEN = os.getenv('ANTHROPIC_API_KEY')
80
- YOUR_OPENAI_TOKEN = os.getenv('OPENAI_API_KEY')
81
-
82
- claude_client = anthropic.Anthropic(api_key=YOUR_ANTHROPIC_TOKEN)
83
- openai_client = openai.OpenAI(api_key=YOUR_OPENAI_TOKEN)
84
-
85
- async def try_claude_api(system_message, claude_messages, timeout=15):
86
- try:
87
- start_time = time.time()
88
- with claude_client.messages.stream(
89
- model="claude-3-5-sonnet-20241022",
90
- max_tokens=7800,
91
- system=system_message,
92
- messages=claude_messages
93
- ) as stream:
94
- collected_content = ""
95
- for chunk in stream:
96
- current_time = time.time()
97
- if current_time - start_time > timeout:
98
- print(f"Claude API response time: {current_time - start_time:.2f} seconds")
99
- raise TimeoutError("Claude API timeout")
100
- if chunk.type == "content_block_delta":
101
- collected_content += chunk.delta.text
102
- yield collected_content
103
- await asyncio.sleep(0)
104
-
105
- start_time = current_time
106
-
107
- except Exception as e:
108
- print(f"Claude API error: {str(e)}")
109
- raise e
110
-
111
- async def try_openai_api(openai_messages):
112
- try:
113
- stream = openai_client.chat.completions.create(
114
- model="gpt-4o",
115
- messages=openai_messages,
116
- stream=True,
117
- max_tokens=4096,
118
- temperature=0.7
119
- )
120
-
121
- collected_content = ""
122
- for chunk in stream:
123
- if chunk.choices[0].delta.content is not None:
124
- collected_content += chunk.choices[0].delta.content
125
- yield collected_content
126
-
127
- except Exception as e:
128
- print(f"OpenAI API error: {str(e)}")
129
- raise e
130
-
131
- class Demo:
132
- def __init__(self):
133
- pass
134
-
135
- async def generation_code(self, query: Optional[str], _setting: Dict[str, str], _history: Optional[History]):
136
- if not query or query.strip() == '':
137
- query = random.choice(DEMO_LIST)['description']
138
-
139
- if _history is None:
140
- _history = []
141
-
142
- messages = history_to_messages(_history, _setting['system'])
143
- system_message = messages[0]['content']
144
-
145
- claude_messages = [
146
- {"role": msg["role"] if msg["role"] != "system" else "user", "content": msg["content"]}
147
- for msg in messages[1:] + [{'role': Role.USER, 'content': query}]
148
- if msg["content"].strip() != ''
149
- ]
150
-
151
- openai_messages = [{"role": "system", "content": system_message}]
152
- for msg in messages[1:]:
153
- openai_messages.append({
154
- "role": msg["role"],
155
- "content": msg["content"]
156
- })
157
- openai_messages.append({"role": "user", "content": query})
158
-
159
- try:
160
- yield [
161
- "Generating code...",
162
- _history,
163
- None,
164
- gr.update(active_key="loading"),
165
- gr.update(open=True)
166
- ]
167
- await asyncio.sleep(0)
168
-
169
- collected_content = None
170
- try:
171
- async for content in try_claude_api(system_message, claude_messages):
172
- yield [
173
- content,
174
- _history,
175
- None,
176
- gr.update(active_key="loading"),
177
- gr.update(open=True)
178
- ]
179
- await asyncio.sleep(0)
180
- collected_content = content
181
-
182
- except Exception as claude_error:
183
- print(f"Falling back to OpenAI API due to Claude error: {str(claude_error)}")
184
-
185
- async for content in try_openai_api(openai_messages):
186
- yield [
187
- content,
188
- _history,
189
- None,
190
- gr.update(active_key="loading"),
191
- gr.update(open=True)
192
- ]
193
- await asyncio.sleep(0)
194
- collected_content = content
195
-
196
- if collected_content:
197
- _history = messages_to_history([
198
- {'role': Role.SYSTEM, 'content': system_message}
199
- ] + claude_messages + [{
200
- 'role': Role.ASSISTANT,
201
- 'content': collected_content
202
- }])
203
-
204
- yield [
205
- collected_content,
206
- _history,
207
- send_to_sandbox(remove_code_block(collected_content)),
208
- gr.update(active_key="render"),
209
- gr.update(open=True)
210
- ]
211
- else:
212
- raise ValueError("No content was generated from either API")
213
-
214
- except Exception as e:
215
- print(f"Error details: {str(e)}")
216
- raise ValueError(f'Error calling APIs: {str(e)}')
217
-
218
- def clear_history(self):
219
- return []
220
-
221
- def remove_code_block(text):
222
- pattern = r'```html\n(.+?)\n```'
223
- match = re.search(pattern, text, re.DOTALL)
224
- if match:
225
- return match.group(1).strip()
226
- else:
227
- return text.strip()
228
-
229
- def history_render(history: History):
230
- return gr.update(open=True), history
231
-
232
- def send_to_sandbox(code):
233
- encoded_html = base64.b64encode(code.encode('utf-8')).decode('utf-8')
234
- data_uri = f"data:text/html;charset=utf-8;base64,{encoded_html}"
235
- return f"<iframe src=\"{data_uri}\" width=\"100%\" height=\"920px\"></iframe>"
236
-
237
- def get_image_base64(image_path):
238
- with open(image_path, "rb") as image_file:
239
- encoded_string = base64.b64encode(image_file.read()).decode()
240
- return encoded_string
241
-
242
- theme = gr.themes.Soft()
243
-
244
- def load_json_data():
245
- # ํ•˜๋“œ์ฝ”๋”ฉ๋œ ๋ฐ์ดํ„ฐ ๋ฐ˜ํ™˜
246
- return [
247
- {
248
- "name": "MBTI ์ง„๋‹จ ์„œ๋น„์Šค",
249
- "image_url": "data:image/png;base64," + get_image_base64('mbti.png'), # mbti.png ์‚ฌ์šฉ
250
- "prompt": "MBTI ์ง„๋‹จ์„ ์œ„ํ•ด 15๊ฐœ์˜ ์งˆ๋ฌธ๊ณผ ๊ฐ๊ด€์‹ ๋‹ต๋ณ€์„ ํ†ตํ•ด MBTI ์ง„๋‹จ ๊ฒฐ๊ณผ ๋ฐ ํ•ด๋‹น ์„ฑ๊ฒฉ์— ๋Œ€ํ•œ ์ƒ์„ธํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•˜๋ผ"
251
- },
252
- {
253
- "name": "ํˆฌ์ž ํฌํŠธํด๋ฆฌ์˜ค ๋Œ€์‹œ๋ณด๋“œ",
254
- "image_url": "data:image/png;base64," + get_image_base64('dash.png'), # mouse.gif ์‚ฌ์šฉ
255
- "prompt": "Create an interactive dashboard with Chart.js showing different types of charts (line, bar, pie) with smooth animations. Include buttons to switch between different data views.ํˆฌ์ž ํฌํŠธํด๋ฆฌ์˜ค๋ฅผ ๋ถ„์„ํ•˜์—ฌ ์œ„ํ—˜๋„, ์ˆ˜์ต๋ฅ , ์ž์‚ฐ ๋ฐฐ๋ถ„์„ ์‹œ๊ฐํ™”ํ•˜๋Š” ํˆฌ์ž ๊ด€๋ฆฌ ๋„๊ตฌ๋ฅผ ๋งŒ๋“œ์„ธ์š”."
256
- },
257
- {
258
- "name": "์ฒด์Šค ๊ฒŒ์ž„",
259
- "image_url": "data:image/png;base64," + get_image_base64('chess.png'), # mouse.gif ์‚ฌ์šฉ
260
- "prompt": "์ฒด์Šค ๊ฒŒ์ž„: ์ฒด์Šค ๊ฒŒ์ž„์˜ ๋ฃฐ์„ ์ •ํ™•ํ•˜๊ฒŒ ์‹๋ณ„ํ•˜๊ณ  ์ ์šฉํ•˜๋ผ, ์ƒ๋Œ€๋ฐฉ์€ auto๋กœ ๊ฒŒ์ž„์„ ์ง„ํ–‰ํ•˜๋ผ"
261
- },
262
- {
263
- "name": "ํƒ€๋กœ์นด๋“œ ์šด์„ธ",
264
- "image_url": "data:image/png;base64," + get_image_base64('tarot.png'), # mouse.gif ์‚ฌ์šฉ
265
- "prompt": "ํƒ€๋กœ์นด๋“œ ์šด์„ธ๋ฅผ ์ ์น˜๋Š”๊ฒƒ์„ ์ƒ์„ฑํ•˜๋ผ. ์•„์ฃผ ์ƒ์„ธํ•˜๊ณ  ์ „๋ฌธ์ ์ด๋ฉด์„œ ์‰ฝ๊ณ  ๊ธธ๊ฒŒ ๋‹ต๋ณ€ํ•˜๋ผ. ๋ชจ๋“  ๋‹ต๋ณ€๊ณผ ์„ค๋ช…์€ ํ•œ๊ธ€๋กœ ํ•˜๋ผ"
266
- },
267
-
268
- {
269
- "name": "ํ…์ŠคํŠธ๋กœ ์Œ์„ฑ ์ƒ์„ฑ ๋ฐ ์กฐ์ •",
270
- "image_url": "data:image/png;base64," + get_image_base64('tts.png'), # mouse.gif ์‚ฌ์šฉ
271
- "prompt": "ํ…์ŠคํŠธ๋ฅผ ์Œ์„ฑ์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ , ์Œ์„ฑ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•˜์„ธ์š”."
272
- },
273
- {
274
- "name": "3D ๋ถ„์ž ์‹œ๋ฎฌ๋ ˆ์ด์…˜",
275
- "image_url": "data:image/png;base64," + get_image_base64('3ds.png'), # mouse.gif ์‚ฌ์šฉ
276
- "prompt": "Three.js๋กœ 3D ๋ถ„์ž ๊ตฌ์กฐ(์ฃผ์š” ๋ถ„์ž๋“ค์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ๊ฒŒ)๋ฅผ ์‹œ๊ฐํ™”ํ•˜์„ธ์š”. ํšŒ์ „, ์คŒ, ์›์ž ์ •๋ณด ํ‘œ์‹œ ๊ธฐ๋Šฅ๊ณผ ์• ๋‹ˆ๋ฉ”์ด์…˜ ํšจ๊ณผ๋ฅผ ๊ตฌํ˜„ํ•˜์„ธ์š”."
277
- },
278
- {
279
- "name": "ํ–‰์šด์˜ ๋ฃฐ๋ ›",
280
- "image_url": "data:image/png;base64," + get_image_base64('roolet.png'), # mouse.gif ์‚ฌ์šฉ
281
- "prompt": "ํ–‰์šด์˜ ์›ํ˜• ๋ฃฐ๋ ›์ด ๋น ๋ฅด๊ฒŒ ๋Œ์•„๊ฐ€๊ณ , ๋งˆ์šฐ์Šค๋กœ ํ™”์‚ด ๋ฐœ์‚ฌ ๋ฒ„ํŠผ ๋ˆ„๋ฅด๋ฉด ๋ฃฐ๋ ›์˜ ๋ฒˆํ˜ธ์— ๋žœ๋คํ•˜๊ฒŒ ๋งž๋Š”๋‹ค. ๊ฐ ๋ฒˆํ˜ธ์— ์ƒ๊ธˆ์ด '๊ฝ' ~ '100๋งŒ์›' ๊นŒ์ง€ ๋žœ๋คํ•˜๊ฒŒ ๋ฐฐ์น˜๋˜์–ด ์žˆ๋‹ค. shoot ์„ ํƒ๋œ ๋ฒˆํ˜ธ์— ๋”ฐ๋ผ ํ•ด๋‹น ๋ฒˆํ˜ธ์— ๋ฐฐ์น˜๋œ ์ƒ๊ธˆ ์•ก์ˆ˜๋„ ์ถœ๋ ฅํ•˜๋ผ"
282
- },
283
-
284
- {
285
- "name": "๋ฒฝ๋Œ๊นจ๊ธฐ ๊ฒŒ์ž„",
286
- "image_url": "data:image/png;base64," + get_image_base64('alcaroid.png'), # mouse.gif ์‚ฌ์šฉ
287
- "prompt": "๋ฒฝ๋Œ๊นจ๊ธฐ ๊ฒŒ์ž„"
288
- },
289
- {
290
- "name": "ํ…Œ์ŠคํŠธ",
291
- "image_url": "data:image/gif;base64," + get_image_base64('mouse.gif'), # mouse.gif ์‚ฌ์šฉ
292
- "prompt": "ํ…Œ์ŠคํŠธ"
293
- }
294
- ]
295
-
296
- def load_session_history(selected_session=None):
297
- try:
298
- json_data = load_json_data()
299
-
300
- html_content = """
301
- <style>
302
- .prompt-grid {
303
- display: grid;
304
- grid-template-columns: repeat(3, 1fr);
305
- gap: 20px;
306
- padding: 20px;
307
- }
308
- .prompt-card {
309
- background: white;
310
- border: 1px solid #eee;
311
- border-radius: 8px;
312
- padding: 15px;
313
- transition: all 0.3s ease;
314
- box-shadow: 0 2px 5px rgba(0,0,0,0.1);
315
- min-height: 300px;
316
- cursor: pointer;
317
- }
318
- .prompt-card:hover {
319
- transform: translateY(-2px);
320
- box-shadow: 0 4px 10px rgba(0,0,0,0.15);
321
- }
322
- .card-image {
323
- width: 100%;
324
- height: 180px;
325
- object-fit: cover;
326
- border-radius: 4px;
327
- margin-bottom: 10px;
328
- }
329
- .card-name {
330
- font-weight: bold;
331
- margin-bottom: 8px;
332
- font-size: 16px;
333
- color: #333;
334
- }
335
- .card-prompt {
336
- font-size: 11px;
337
- line-height: 1.4;
338
- color: #666;
339
- display: -webkit-box;
340
- -webkit-line-clamp: 6;
341
- -webkit-box-orient: vertical;
342
- overflow: hidden;
343
- text-overflow: ellipsis;
344
- height: 90px;
345
- background-color: #f8f9fa;
346
- padding: 8px;
347
- border-radius: 4px;
348
- border: 1px solid #eee;
349
- }
350
- </style>
351
- <div class="prompt-grid">
352
- """
353
-
354
- for item in json_data:
355
- html_content += f"""
356
- <div class="prompt-card">
357
- <img src="{item.get('image_url', '')}" class="card-image" alt="{html.escape(item.get('name', ''))}">
358
- <div class="card-name">{html.escape(item.get('name', ''))}</div>
359
- <div class="card-prompt">{html.escape(item.get('prompt', ''))}</div>
360
- </div>
361
- """
362
-
363
- html_content += """
364
- </div>
365
- """
366
-
367
- return gr.HTML(value=html_content)
368
-
369
- except Exception as e:
370
- print(f"Error in load_session_history: {str(e)}")
371
- return gr.HTML("Error loading templates")
372
-
373
- # Demo ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
374
- demo_instance = Demo()
375
-
376
-
377
-
378
-
379
- with gr.Blocks(css_paths="app.css",theme=theme) as demo:
380
- history = gr.State([])
381
- setting = gr.State({
382
- "system": SystemPrompt,
383
- })
384
-
385
- with ms.Application() as app:
386
- with antd.ConfigProvider():
387
- # Drawer ์ปดํฌ๋„ŒํŠธ๋“ค
388
- with antd.Drawer(open=False, title="code", placement="left", width="750px") as code_drawer:
389
- code_output = legacy.Markdown()
390
-
391
- with antd.Drawer(open=False, title="history", placement="left", width="900px") as history_drawer:
392
- history_output = legacy.Chatbot(show_label=False, flushing=False, height=960, elem_classes="history_chatbot")
393
-
394
- with antd.Drawer(
395
- open=False,
396
- title="Templates",
397
- placement="right",
398
- width="900px",
399
- elem_classes="session-drawer"
400
- ) as session_drawer:
401
- with antd.Flex(vertical=True, gap="middle"):
402
- gr.Markdown("### Available Templates")
403
- session_history = gr.HTML(
404
- elem_classes="session-history"
405
- )
406
- close_btn = antd.Button(
407
- "Close",
408
- type="default",
409
- elem_classes="close-btn"
410
- )
411
-
412
- # ์„ธ์…˜ ๋“œ๋กœ์–ด์—์„œ ์นด๋“œ ํด๋ฆญ ์‹œ ์‹คํ–‰ํ•  ํ•จ์ˆ˜ (Drawer ์ปดํฌ๋„ŒํŠธ๋“ค ๋‹ค์Œ์— ์œ„์น˜)
413
- def execute_history_item(evt: gr.SelectData): # gr.SelectData๋กœ ์ด๋ฒคํŠธ ๋ฐ์ดํ„ฐ ๋ฐ›๊ธฐ
414
- try:
415
- # ํด๋ฆญ๋œ ์นด๋“œ์˜ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ
416
- prompt = evt.value["prompt"]
417
- response = evt.value["response"]
418
-
419
- # ์ฝ”๋“œ ์‹คํ–‰
420
- code = remove_code_block(response) if '```html' in response else response
421
-
422
- return (
423
- gr.update(value=prompt), # ์ž…๋ ฅ ํ•„๋“œ ์—…๋ฐ์ดํŠธ
424
- send_to_sandbox(code), # ์ฝ”๋“œ ์‹คํ–‰
425
- gr.update(active_key="render"), # ํƒญ ์ƒํƒœ ์—…๋ฐ์ดํŠธ
426
- gr.update(open=False) # ์„ธ์…˜ ๋“œ๋กœ์–ด ๋‹ซ๊ธฐ
427
- )
428
- except Exception as e:
429
- print(f"Error executing history item: {e}")
430
- return None, None, gr.update(active_key="empty"), gr.update(open=True)
431
-
432
- # ๋ฉ”์ธ ์ปจํ…์ธ ๋ฅผ ์œ„ํ•œ Row
433
- with antd.Row(gutter=[32, 12]) as layout:
434
- # ์ขŒ์ธก ํŒจ๋„
435
- with antd.Col(span=24, md=8):
436
- with antd.Flex(vertical=True, gap="middle", wrap=True):
437
- header = gr.HTML(f"""
438
- <div class="left_header">
439
- <img src="data:image/gif;base64,{get_image_base64('mouse.gif')}" width="360px" />
440
- <h1 style="font-size: 18px;">๊ณ ์–‘์ด๋„ ๋ฐœ๋กœ ์ฝ”๋”ฉํ•˜๋Š” 'MOUSE-I'</h2>
441
- <h1 style="font-size: 10px;">์ž…๋ ฅ์—†์ด 'Send' ๋ฒ„ํŠผ ํด๋ฆญ์‹œ ๋žœ๋คํ•œ ์˜ˆ์ œ ์ฝ”๋“œ ์ƒ์„ฑ. ์ƒ์„ฑ๋œ ์ฝ”๋“œ๋งŒ ํ”„๋กฌํ”„ํŠธ์— ๋ถ™์—ฌ๋„ฃ๊ณ  'Code ์‹คํ–‰' ๋ฒ„ํŠผ ํด๋ฆญ์‹œ ํ™”๋ฉด์— ์ฆ‰์‹œ ์„œ๋น„์Šค๊ฐ€ ์‹คํ–‰. ๋ฌธ์˜: [email protected] </h2>
442
- </div>
443
- """)
444
- input = antd.InputTextarea(
445
- size="large",
446
- allow_clear=True,
447
- placeholder=random.choice(DEMO_LIST)['description']
448
- )
449
-
450
- # ๋ฒ„ํŠผ๋“ค์„ ๊ฐ€๋กœ๋กœ ๋ฐฐ์น˜ํ•˜๊ธฐ ์œ„ํ•œ Flex ์ปจํ…Œ์ด๋„ˆ
451
- with antd.Flex(gap="small", justify="space-between"):
452
- btn = antd.Button("Send", type="primary", size="large")
453
- execute_btn = antd.Button("Code ์‹คํ–‰", type="default", size="large")
454
- clear_btn = antd.Button("Clear", type="default", size="large")
455
-
456
-
457
- # ์šฐ์ธก ํŒจ๋„
458
- with antd.Col(span=24, md=16):
459
- with ms.Div(elem_classes="right_panel"):
460
- with antd.Flex(gap="small", elem_classes="setting-buttons"):
461
- codeBtn = antd.Button("๐Ÿง‘โ€๐Ÿ’ป ์ฝ”๋“œ ๋ณด๊ธฐ", type="default")
462
- historyBtn = antd.Button("๐Ÿ“œ ํžˆ์Šคํ† ๋ฆฌ", type="default")
463
- sessionBtn = antd.Button("๐Ÿ“š ํ…œํ”Œ๋ฆฟ", type="default")
464
-
465
- gr.HTML('<div class="render_header"><span class="header_btn"></span><span class="header_btn"></span><span class="header_btn"></span></div>')
466
- with antd.Tabs(active_key="empty", render_tab_bar="() => null") as state_tab:
467
- with antd.Tabs.Item(key="empty"):
468
- empty = antd.Empty(description="empty input", elem_classes="right_content")
469
- with antd.Tabs.Item(key="loading"):
470
- loading = antd.Spin(True, tip="coding...", size="large", elem_classes="right_content")
471
- with antd.Tabs.Item(key="render"):
472
- sandbox = gr.HTML(elem_classes="html_content")
473
-
474
- # Code ์‹คํ–‰ ๋ฒ„ํŠผ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜ ์ •์˜
475
- def execute_code(query: str):
476
- if not query or query.strip() == '':
477
- return None, gr.update(active_key="empty")
478
-
479
- try:
480
- # HTML ์ฝ”๋“œ ๋ธ”๋ก ํ™•์ธ
481
- if '```html' in query and '```' in query:
482
- # HTML ์ฝ”๋“œ ๋ธ”๋ก ์ถ”์ถœ
483
- code = remove_code_block(query)
484
- else:
485
- # ์ž…๋ ฅ๋œ ํ…์ŠคํŠธ๋ฅผ ๊ทธ๋Œ€๋กœ ์ฝ”๋“œ๋กœ ์‚ฌ์šฉ
486
- code = query.strip()
487
-
488
- return send_to_sandbox(code), gr.update(active_key="render")
489
- except Exception as e:
490
- print(f"Error executing code: {str(e)}")
491
- return None, gr.update(active_key="empty")
492
-
493
- # ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋“ค
494
- execute_btn.click(
495
- fn=execute_code,
496
- inputs=[input],
497
- outputs=[sandbox, state_tab]
498
- )
499
-
500
- codeBtn.click(
501
- lambda: gr.update(open=True),
502
- inputs=[],
503
- outputs=[code_drawer]
504
- )
505
-
506
- code_drawer.close(
507
- lambda: gr.update(open=False),
508
- inputs=[],
509
- outputs=[code_drawer]
510
- )
511
-
512
- historyBtn.click(
513
- history_render,
514
- inputs=[history],
515
- outputs=[history_drawer, history_output]
516
- )
517
-
518
- history_drawer.close(
519
- lambda: gr.update(open=False),
520
- inputs=[],
521
- outputs=[history_drawer]
522
- )
523
-
524
-
525
- # ์„ธ์…˜ ๋ฒ„ํŠผ ํด๋ฆญ ์ด๋ฒคํŠธ ์ˆ˜์ •
526
-
527
- sessionBtn.click(
528
- fn=lambda: (gr.update(open=True), load_session_history()),
529
- inputs=[],
530
- outputs=[session_drawer, session_history]
531
- )
532
- # ์„ธ์…˜ ๋“œ๋กœ์–ด ๋‹ซ๊ธฐ ์ด๋ฒคํŠธ ์ˆ˜์ •
533
- session_drawer.close(
534
- lambda: (gr.update(open=False), gr.HTML("")),
535
- outputs=[session_drawer, session_history]
536
- )
537
-
538
- close_btn.click(
539
- lambda: (gr.update(open=False), gr.HTML("")),
540
- outputs=[session_drawer, session_history]
541
- )
542
-
543
-
544
-
545
- btn.click(
546
- demo_instance.generation_code,
547
- inputs=[input, setting, history],
548
- outputs=[code_output, history, sandbox, state_tab, code_drawer]
549
- )
550
-
551
- clear_btn.click(
552
- demo_instance.clear_history,
553
- inputs=[],
554
- outputs=[history]
555
- )
556
-
557
- # ๋งˆ์ง€๋ง‰ ๋ถ€๋ถ„์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ•˜์„ธ์š”
558
-
559
- if __name__ == "__main__":
560
- try:
561
- demo_instance = Demo()
562
- demo.queue(default_concurrency_limit=20).launch(ssr_mode=False)
563
- except Exception as e:
564
- print(f"Initialization error: {e}")
565
- raise