unnastyle commited on
Commit
3634c66
ยท
verified ยท
1 Parent(s): 6e5bc1e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +83 -92
app.py CHANGED
@@ -7,21 +7,6 @@ import requests
7
  # ๋””๋ฒ„๊น… ๋กœ๊น… ์„ค์ • (์ „์ฒด ํ†ตํ•ฉ์„ ์œ„ํ•ด ํฌ๋งท ํฌํ•จ)
8
  logging.basicConfig(level=logging.DEBUG, format="%(asctime)s - %(levelname)s - %(message)s")
9
 
10
- # ---------- ์‚ฌ์šฉ์ž ์ •์˜ CSS (์™ผ์ชฝ๊ณผ ์˜ค๋ฅธ์ชฝ ์˜์—ญ์˜ ๋†’์ด๋ฅผ ๋™์ผํ•˜๊ฒŒ ๋งž์ถค) ----------
11
- css = """
12
- <style>
13
- /* ์™ผ์ชฝ '์ „์ฒด ํŽ˜์ด์ง€ HTML ์ž…๋ ฅ' ์˜์—ญ์˜ textarea ๋†’์ด ์„ค์ • */
14
- #html_input textarea {
15
- height: 400px !important;
16
- }
17
- /* ์˜ค๋ฅธ์ชฝ ์˜์—ญ์„ ๊ฐ์‹ธ๋Š” ์ปจํ…Œ์ด๋„ˆ์˜ ๋†’์ด ์„ค์ • */
18
- #right_panel {
19
- height: 400px;
20
- overflow-y: auto;
21
- }
22
- </style>
23
- """
24
-
25
  # ---------- [๋ชจ๋“ˆ1: ๊ธฐ์กด ๊ธฐ๋ณธ์ฝ”๋“œ] ์‹œ์ž‘ ----------
26
  # ์˜์–ด ์›”์„ ํ•œ๊ตญ์–ด ์›”๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ ์œ„ํ•œ ๋งคํ•‘
27
  month_mapping = {
@@ -228,13 +213,14 @@ def update_lecture_and_urls(selected_section, sections_dict):
228
  ์„ ํƒํ•œ ์„น์…˜์„ ๋ฐ”ํƒ•์œผ๋กœ ๊ฐ•์˜ ๋ชฉ๋ก ํ…์ŠคํŠธ์™€ URL๋“ค์„ ์ถ”์ถœํ•˜์—ฌ
229
  - ๊ฐ•์˜ ๋ชฉ๋ก ํ…์ŠคํŠธ(์—†์œผ๋ฉด "๊ฐ•์˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค" ๋ฐ˜ํ™˜)
230
  - ์ตœ๋Œ€ 3๊ฐœ์˜ ๊ฐ•์˜ URL (๊ฐ•์˜ URL์ด ์—†์œผ๋ฉด ๋นˆ ๋ฌธ์ž์—ด)
231
- ์„ ๋ฐ˜ํ™˜.
232
  """
233
  if not selected_section or not sections_dict:
234
  return "", "", "", ""
235
  lectures_text, url_list = sections_dict.get(selected_section, ("", []))
236
  if not lectures_text:
237
  lectures_text = "๊ฐ•์˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค"
 
238
  url1 = url_list[0] if len(url_list) >= 1 else ""
239
  url2 = url_list[1] if len(url_list) >= 2 else ""
240
  url3 = url_list[2] if len(url_list) >= 3 else ""
@@ -323,6 +309,7 @@ def process_full(lecture_url):
323
  """
324
  ์ž…๋ ฅ๋œ ๊ฐ•์˜ URL๋กœ๋ถ€ํ„ฐ ์Šคํฌ๋ฆฝํŠธ URL์„ ์ƒ์„ฑํ•˜๊ณ ,
325
  ํ•ด๋‹น ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๊ฐ€์ ธ์˜จ ํ›„ ํƒ€์ž„๋ผ์ธ์„ ์ œ๊ฑฐํ•œ ์ตœ์ข… ๊ฐ•์˜ ๋‚ด์šฉ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜.
 
326
  """
327
  script_url = create_script_url(lecture_url)
328
  if not script_url:
@@ -339,6 +326,7 @@ def process_full(lecture_url):
339
  # ---------- [๋ชจ๋“ˆ3: ๊ฐ•์˜ ๋‚ด์šฉ ํ•ฉ์น˜๊ธฐ ์ถ”๊ฐ€์ฝ”๋“œ] ์‹œ์ž‘ ----------
340
  with gr.Blocks() as merge_demo:
341
  gr.Markdown("## ๊ฐ•์˜ ๋‚ด์šฉ ํ•ฉ์น˜๊ธฐ")
 
342
  merged_content = gr.Textbox(label="์ „์ฒด ๊ฐ•์˜ ๋‚ด์šฉ", lines=10, elem_id="merged_content")
343
  with gr.Row():
344
  merge_copy_btn = gr.Button("์ „์ฒด ๊ฐ•์˜ ๋‚ด์šฉ ๋ณต์‚ฌํ•˜๊ธฐ", elem_id="merge_copy_btn")
@@ -438,76 +426,12 @@ def handle_fetch_all(lecture_list_text):
438
  # ---------- ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ๋ ----------
439
 
440
  # ---------- ํ†ตํ•ฉ Gradio ์•ฑ ๊ตฌ์„ฑ (ํ•œ ํŽ˜์ด์ง€์— ๋ชจ๋‘ ํ‘œ์‹œ) ----------
441
- with gr.Blocks() as additional_demo:
442
- # [๋ชจ๋“ˆ2] - ๊ฐ•์˜ ๋‚ด์šฉ ๊ฐ€์ ธ์˜ค๊ธฐ ์˜์—ญ (์‚ญ์ œ๋‚ด์šฉ ์ œ๊ฑฐ ๋ฐ ํƒ€์ดํ‹€ ์ˆ˜์ •)
443
- gr.Markdown("## ๊ฐ•์˜ ๋‚ด์šฉ ๊ฐ€์ ธ์˜ค๊ธฐ")
444
- with gr.Row():
445
- url1 = gr.Textbox(label="๊ฐ•์˜1 URL", elem_id="url1")
446
- url2 = gr.Textbox(label="๊ฐ•์˜2 URL", elem_id="url2")
447
- url3 = gr.Textbox(label="๊ฐ•์˜3 URL", elem_id="url3")
448
- with gr.Row():
449
- # ๊ฐœ๋ณ„ '๊ฐ•์˜ ๋‚ด์šฉ ๊ฐ€์ ธ์˜ค๊ธฐ' ๋ฒ„ํŠผ์€ ์‚ญ์ œ๋จ (์š”์ฒญ์‚ฌํ•ญ์— ๋”ฐ๋ผ ์ œ๊ฑฐ)
450
- pass
451
- with gr.Row():
452
- lecture_content1 = gr.Textbox(label="๊ฐ•์˜ ๋‚ด์šฉ", lines=10, elem_id="lecture_content1")
453
- lecture_content2 = gr.Textbox(label="๊ฐ•์˜ ๋‚ด์šฉ", lines=10, elem_id="lecture_content2")
454
- lecture_content3 = gr.Textbox(label="๊ฐ•์˜ ๋‚ด์šฉ", lines=10, elem_id="lecture_content3")
455
- with gr.Row():
456
- copy_btn1 = gr.Button("๊ฐ•์˜ ๋‚ด์šฉ ๋ณต์‚ฌํ•˜๊ธฐ", elem_id="copy_btn1")
457
- copy_btn2 = gr.Button("๊ฐ•์˜ ๋‚ด์šฉ ๋ณต์‚ฌํ•˜๊ธฐ", elem_id="copy_btn2")
458
- copy_btn3 = gr.Button("๊ฐ•์˜ ๋‚ด์šฉ ๋ณต์‚ฌํ•˜๊ธฐ", elem_id="copy_btn3")
459
- with gr.Row():
460
- copy_result1 = gr.Textbox(label="๊ฐ•์˜ ๋‚ด์šฉ ๋ณต์‚ฌํ•˜๊ธฐ ๊ฒฐ๊ณผ", interactive=False, elem_id="copy_result1")
461
- copy_result2 = gr.Textbox(label="๊ฐ•์˜ ๋‚ด์šฉ ๋ณต์‚ฌํ•˜๊ธฐ ๊ฒฐ๊ณผ", interactive=False, elem_id="copy_result2")
462
- copy_result3 = gr.Textbox(label="๊ฐ•์˜ ๋‚ด์šฉ ๋ณต์‚ฌํ•˜๊ธฐ ๊ฒฐ๊ณผ", interactive=False, elem_id="copy_result3")
463
-
464
- custom_script = """
465
- <script>
466
- function setupCopy(copyBtnId, textBoxId, resultBoxId) {
467
- const copyBtn = document.getElementById(copyBtnId);
468
- if (!copyBtn) {
469
- console.error("๋ฒ„ํŠผ " + copyBtnId + "๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.");
470
- return;
471
- }
472
- copyBtn.addEventListener("click", function(){
473
- const textBoxElem = document.getElementById(textBoxId);
474
- const resultBoxElem = document.getElementById(resultBoxId);
475
- if(textBoxElem && resultBoxElem) {
476
- const textarea = textBoxElem.querySelector("textarea");
477
- const resultTextarea = resultBoxElem.querySelector("textarea");
478
- if(textarea && resultTextarea) {
479
- var text = textarea.value;
480
- if(text.trim() === ""){
481
- resultTextarea.value = "๋ณต์‚ฌํ•  ๋‚ด์šฉ์ด ๏ฟฝ๏ฟฝ์Šต๋‹ˆ๋‹ค.";
482
- } else {
483
- navigator.clipboard.writeText(text).then(function(){
484
- resultTextarea.value = "๋ณต์‚ฌ์™„๋ฃŒ";
485
- }, function(err){
486
- resultTextarea.value = "๋ณต์‚ฌ ์‹คํŒจ";
487
- });
488
- }
489
- }
490
- }
491
- });
492
- }
493
- document.addEventListener("DOMContentLoaded", function(){
494
- setupCopy("copy_btn1", "lecture_content1", "copy_result1");
495
- setupCopy("copy_btn2", "lecture_content2", "copy_result2");
496
- setupCopy("copy_btn3", "lecture_content3", "copy_result3");
497
- });
498
- </script>
499
- """
500
- gr.HTML(custom_script)
501
- # (์‚ญ์ œ๋‚ด์šฉ ๊ด€๋ จ gr.Markdown ์ œ๊ฑฐ)
502
-
503
  with gr.Blocks() as app:
504
- gr.HTML(css) # ์‚ฌ์šฉ์ž ์ •์˜ CSS ์‚ฝ์ž…
505
  gr.Markdown("# ์บ๋กค๋ผ์ธ๋Œ€ํ•™ ๊ฐ•์˜ ์ถ”์ถœ๊ธฐ")
506
- gr.Markdown("[์‚ฌ์šฉ๋ฐฉ๋ฒ•] \n1. ์ถ”์ถœ์„ ์›ํ•˜๋Š” ๊ฐ•์˜ ํŽ˜์ด์ง€์—์„œ \"Ctrl + U\"๋ฅผ ๋ˆŒ๋Ÿฌ ํŽ˜์ด์ง€ ์†Œ์Šค๋ฅผ ํ™•์ธํ•˜๊ฑฐ๋‚˜, ๋งˆ์šฐ์Šค ์šฐํด๋ฆญ ํ›„ \"ํŽ˜์ด์ง€ ์†Œ์Šค ๋ณด๊ธฐ\"๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. \n2. ํŽ˜์ด์ง€ ์†Œ์Šค์—์„œ ์ „์ฒด ๋ณต์‚ฌ ํ•ฉ๋‹ˆ๋‹ค. (\"Ctrl+A\" โ†’ \"Ctrl+C\")\n3. ๋ณต์‚ฌํ•œ ๋‚ด์šฉ์„ ํ•ด๋‹น ํŽ˜์ด์ง€ \"์ „์ฒด ํŽ˜์ด์ง€ HTML ์ž…๋ ฅ\"์— ๋ถ™์—ฌ ๋†“๊ณ (Ctrl+V) \"Submit\" ๋ฒ„ํŠผ์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.\n4. ์˜ค๋ฅธ์ชฝ ์ฐฝ์—์„œ ์›ํ•˜๋Š” ์„น์…˜์„ ์„ ํƒ ํ›„ \"๊ฐ•์˜ ๋‚ด์šฉ ๊ฐ€์ ธ์˜ค๊ธฐ\" ๋ฒ„ํŠผ์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.\n5. ๊ฐ€์ ธ์˜จ ๊ฐ•์˜ ๋‚ด์šฉ ์ค‘์—์„œ ํ•„์š”ํ•œ ๋‚ด์šฉ๋งŒ ๋ณต์‚ฌํ•˜์—ฌ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.")
507
- gr.HTML(
508
  """
509
  <div style="background-color: #f0f0f0; padding: 10px; margin-bottom: 20px;">
510
- <strong>[์‚ฌ์šฉ๋ฐฉ๋ฒ•]</strong>
511
  <ol>
512
  <li>์ถ”์ถœ์„ ์›ํ•˜๋Š” ๊ฐ•์˜ ํŽ˜์ด์ง€์—์„œ "Ctrl + U"๋ฅผ ๋ˆŒ๋Ÿฌ ํŽ˜์ด์ง€ ์†Œ์Šค๋ฅผ ํ™•์ธํ•˜๊ฑฐ๋‚˜, ๋งˆ์šฐ์Šค ์šฐํด๋ฆญ ํ›„ "ํŽ˜์ด์ง€ ์†Œ์Šค ๋ณด๊ธฐ"๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.</li>
513
  <li>ํŽ˜์ด์ง€ ์†Œ์Šค์—์„œ ์ „์ฒด ๋ณต์‚ฌ ํ•ฉ๋‹ˆ๋‹ค. ("Ctrl+A" โ†’ "Ctrl+C")</li>
@@ -518,17 +442,18 @@ with gr.Blocks() as app:
518
  </div>
519
  """
520
  )
521
- # ๋ชจ๋“ˆ1: HTML ์ž…๋ ฅ ๋ฐ ๊ณผ๋ชฉ/์„น์…˜ ํ‘œ์‹œ (์™ผ์ชฝ๊ณผ ์˜ค๋ฅธ์ชฝ ์˜์—ญ์˜ ๋†’์ด๋ฅผ ๋™์ผํ•˜๊ฒŒ ๋งž์ถค)
522
  with gr.Tab("HTML ํŒŒ์‹ฑ ๋ฐ ์„น์…˜ ์„ ํƒ"):
523
  with gr.Row():
524
  with gr.Column():
525
- html_input = gr.Textbox(label="์ „์ฒด ํŽ˜์ด์ง€ HTML ์ž…๋ ฅ", lines=20, placeholder="HTML ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”...", elem_id="html_input")
526
  parse_btn = gr.Button("Submit")
527
- with gr.Column(elem_id="right_panel"):
528
- subject_out = gr.Textbox(label="๊ณผ๋ชฉ๋ช…", interactive=False, lines=20)
529
  section_dropdown = gr.Dropdown(label="์„น์…˜ ์„ ํƒ", choices=[], interactive=True)
530
- lecture_out = gr.Textbox(label="์„ ํƒํ•œ ์„น์…˜ ๊ฐ•์˜ ๋ชฉ๋ก", lines=20, interactive=False)
531
  with gr.Row():
 
532
  fetch_all_btn = gr.Button("๊ฐ•์˜ ๋‚ด์šฉ ๊ฐ€์ ธ์˜ค๊ธฐ", elem_id="fetch_all_btn")
533
  sections_state = gr.State()
534
 
@@ -537,21 +462,87 @@ with gr.Blocks() as app:
537
  inputs=html_input,
538
  outputs=[subject_out, section_dropdown, sections_state]
539
  )
540
- # ์„น์…˜ ์„ ํƒ ์‹œ ๊ฐ•์˜๋ชฉ๋ก ํ…์ŠคํŠธ๋งŒ ์—…๋ฐ์ดํŠธ
541
  section_dropdown.change(
542
  fn=update_lecture_text_only,
543
  inputs=[section_dropdown, sections_state],
544
  outputs=lecture_out
545
  )
546
- # "๊ฐ•์˜ ๋‚ด์šฉ ๊ฐ€์ ธ์˜ค๊ธฐ" ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ๊ฐ•์˜ URL๊ณผ ๋‚ด์šฉ ์—…๋ฐ์ดํŠธ ([ํ–‰๋™] ์‹คํ–‰)
547
  fetch_all_btn.click(
548
  fn=handle_fetch_all,
549
  inputs=lecture_out,
550
- outputs=[url1, url2, url3, lecture_content1, lecture_content2, lecture_content3, merged_content]
 
 
 
 
 
551
  )
552
 
553
- gr.Markdown("---")
554
- # (์‚ญ์ œ๋‚ด์šฉ ๊ด€๋ จ gr.Markdown ์ œ๊ฑฐ)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
555
  additional_demo.render()
556
  merge_demo.render()
557
 
 
7
  # ๋””๋ฒ„๊น… ๋กœ๊น… ์„ค์ • (์ „์ฒด ํ†ตํ•ฉ์„ ์œ„ํ•ด ํฌ๋งท ํฌํ•จ)
8
  logging.basicConfig(level=logging.DEBUG, format="%(asctime)s - %(levelname)s - %(message)s")
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  # ---------- [๋ชจ๋“ˆ1: ๊ธฐ์กด ๊ธฐ๋ณธ์ฝ”๋“œ] ์‹œ์ž‘ ----------
11
  # ์˜์–ด ์›”์„ ํ•œ๊ตญ์–ด ์›”๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ ์œ„ํ•œ ๋งคํ•‘
12
  month_mapping = {
 
213
  ์„ ํƒํ•œ ์„น์…˜์„ ๋ฐ”ํƒ•์œผ๋กœ ๊ฐ•์˜ ๋ชฉ๋ก ํ…์ŠคํŠธ์™€ URL๋“ค์„ ์ถ”์ถœํ•˜์—ฌ
214
  - ๊ฐ•์˜ ๋ชฉ๋ก ํ…์ŠคํŠธ(์—†์œผ๋ฉด "๊ฐ•์˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค" ๋ฐ˜ํ™˜)
215
  - ์ตœ๋Œ€ 3๊ฐœ์˜ ๊ฐ•์˜ URL (๊ฐ•์˜ URL์ด ์—†์œผ๋ฉด ๋นˆ ๋ฌธ์ž์—ด)
216
+ ๋ฅผ ๋ฐ˜ํ™˜.
217
  """
218
  if not selected_section or not sections_dict:
219
  return "", "", "", ""
220
  lectures_text, url_list = sections_dict.get(selected_section, ("", []))
221
  if not lectures_text:
222
  lectures_text = "๊ฐ•์˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค"
223
+ # ๊ฐ•์˜ URL 3๊ฐœ ์ฑ„์šฐ๊ธฐ (์—†์œผ๋ฉด ๋นˆ ๋ฌธ์ž์—ด)
224
  url1 = url_list[0] if len(url_list) >= 1 else ""
225
  url2 = url_list[1] if len(url_list) >= 2 else ""
226
  url3 = url_list[2] if len(url_list) >= 3 else ""
 
309
  """
310
  ์ž…๋ ฅ๋œ ๊ฐ•์˜ URL๋กœ๋ถ€ํ„ฐ ์Šคํฌ๋ฆฝํŠธ URL์„ ์ƒ์„ฑํ•˜๊ณ ,
311
  ํ•ด๋‹น ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๊ฐ€์ ธ์˜จ ํ›„ ํƒ€์ž„๋ผ์ธ์„ ์ œ๊ฑฐํ•œ ์ตœ์ข… ๊ฐ•์˜ ๋‚ด์šฉ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜.
312
+ (์ค‘๊ฐ„ ๋‹จ๊ณ„๋Š” ์ถœ๋ ฅํ•˜์ง€ ์•Š๊ณ  ์ตœ์ข… ๊ฒฐ๊ณผ๋งŒ ๋ฐ˜ํ™˜)
313
  """
314
  script_url = create_script_url(lecture_url)
315
  if not script_url:
 
326
  # ---------- [๋ชจ๋“ˆ3: ๊ฐ•์˜ ๋‚ด์šฉ ํ•ฉ์น˜๊ธฐ ์ถ”๊ฐ€์ฝ”๋“œ] ์‹œ์ž‘ ----------
327
  with gr.Blocks() as merge_demo:
328
  gr.Markdown("## ๊ฐ•์˜ ๋‚ด์šฉ ํ•ฉ์น˜๊ธฐ")
329
+ # "๊ฐ•์˜๋‚ด์šฉ ํ•ฉ์น˜๊ธฐ" ๋ฒ„ํŠผ ์‚ญ์ œ (์š”์ฒญ์‚ฌํ•ญ์— ๋”ฐ๋ผ ์‚ญ์ œ)
330
  merged_content = gr.Textbox(label="์ „์ฒด ๊ฐ•์˜ ๋‚ด์šฉ", lines=10, elem_id="merged_content")
331
  with gr.Row():
332
  merge_copy_btn = gr.Button("์ „์ฒด ๊ฐ•์˜ ๋‚ด์šฉ ๋ณต์‚ฌํ•˜๊ธฐ", elem_id="merge_copy_btn")
 
426
  # ---------- ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ๋ ----------
427
 
428
  # ---------- ํ†ตํ•ฉ Gradio ์•ฑ ๊ตฌ์„ฑ (ํ•œ ํŽ˜์ด์ง€์— ๋ชจ๋‘ ํ‘œ์‹œ) ----------
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
429
  with gr.Blocks() as app:
 
430
  gr.Markdown("# ์บ๋กค๋ผ์ธ๋Œ€ํ•™ ๊ฐ•์˜ ์ถ”์ถœ๊ธฐ")
431
+ gr.Markdown(
 
432
  """
433
  <div style="background-color: #f0f0f0; padding: 10px; margin-bottom: 20px;">
434
+ <strong>์‚ฌ์šฉ๋ฐฉ๋ฒ•</strong>
435
  <ol>
436
  <li>์ถ”์ถœ์„ ์›ํ•˜๋Š” ๊ฐ•์˜ ํŽ˜์ด์ง€์—์„œ "Ctrl + U"๋ฅผ ๋ˆŒ๋Ÿฌ ํŽ˜์ด์ง€ ์†Œ์Šค๋ฅผ ํ™•์ธํ•˜๊ฑฐ๋‚˜, ๋งˆ์šฐ์Šค ์šฐํด๋ฆญ ํ›„ "ํŽ˜์ด์ง€ ์†Œ์Šค ๋ณด๊ธฐ"๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.</li>
437
  <li>ํŽ˜์ด์ง€ ์†Œ์Šค์—์„œ ์ „์ฒด ๋ณต์‚ฌ ํ•ฉ๋‹ˆ๋‹ค. ("Ctrl+A" โ†’ "Ctrl+C")</li>
 
442
  </div>
443
  """
444
  )
445
+ # ๋ชจ๋“ˆ1: HTML ์ž…๋ ฅ ๋ฐ ์˜ค๋ฅธ์ชฝ์— ๊ณผ๋ชฉ/์„น์…˜/๊ฐ•์˜ ๋ชฉ๋ก ํ‘œ์‹œ
446
  with gr.Tab("HTML ํŒŒ์‹ฑ ๋ฐ ์„น์…˜ ์„ ํƒ"):
447
  with gr.Row():
448
  with gr.Column():
449
+ html_input = gr.Textbox(label="์ „์ฒด ํŽ˜์ด์ง€ HTML ์ž…๋ ฅ", lines=20, placeholder="HTML ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”...")
450
  parse_btn = gr.Button("Submit")
451
+ with gr.Column():
452
+ subject_out = gr.Textbox(label="๊ณผ๋ชฉ๋ช…", interactive=False)
453
  section_dropdown = gr.Dropdown(label="์„น์…˜ ์„ ํƒ", choices=[], interactive=True)
454
+ lecture_out = gr.Textbox(label="์„ ํƒํ•œ ์„น์…˜ ๊ฐ•์˜ ๋ชฉ๋ก", lines=10, interactive=False)
455
  with gr.Row():
456
+ # [์š”์ฒญ์‚ฌํ•ญ]์— ๋”ฐ๋ผ "์„ ํƒํ•œ ์„น์…˜ ๊ฐ•์˜ ๋ชฉ๋ก" ์•„๋ž˜์— '๊ฐ•์˜ ๋‚ด์šฉ ๊ฐ€์ ธ์˜ค๊ธฐ' ๋ฒ„ํŠผ ์ถ”๊ฐ€
457
  fetch_all_btn = gr.Button("๊ฐ•์˜ ๋‚ด์šฉ ๊ฐ€์ ธ์˜ค๊ธฐ", elem_id="fetch_all_btn")
458
  sections_state = gr.State()
459
 
 
462
  inputs=html_input,
463
  outputs=[subject_out, section_dropdown, sections_state]
464
  )
465
+ # ์„น์…˜ ์„ ํƒ์‹œ ๊ฐ•์˜๋ชฉ๋ก ํ…์ŠคํŠธ๋งŒ ์—…๋ฐ์ดํŠธํ•˜๋Š” ์ด๋ฒคํŠธ ๋“ฑ๋ก
466
  section_dropdown.change(
467
  fn=update_lecture_text_only,
468
  inputs=[section_dropdown, sections_state],
469
  outputs=lecture_out
470
  )
471
+ # "๊ฐ•์˜ ๋‚ด์šฉ ๊ฐ€์ ธ์˜ค๊ธฐ" ๋ฒ„ํŠผ ํด๋ฆญ์‹œ ๊ฐ•์˜ URL๊ณผ ๋‚ด์šฉ ์—…๋ฐ์ดํŠธ (๋ฒ„ํŠผ ํด๋ฆญ ์‹œ [ํ–‰๋™] ์‹คํ–‰)
472
  fetch_all_btn.click(
473
  fn=handle_fetch_all,
474
  inputs=lecture_out,
475
+ outputs=[None, None, None,
476
+ # ํ•ด๋‹น ์ถœ๋ ฅ์€ ๊ฐ•์˜ URL์ฐฝ ์•„๋ž˜์— ์œ„์น˜ํ•œ ๊ฐœ๋ณ„ ๊ฐ•์˜ ๋‚ด์šฉ ํ…์ŠคํŠธ๋ฐ•์Šค๋“ค์— ๋Œ€์‘
477
+ # URL ํ…์ŠคํŠธ๋ฐ•์Šค๋Š” ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•˜์ง€๋งŒ ์‚ญ์ œ๋œ ๋‚ด์šฉ์ด ์ถœ๋ ฅ๋˜์ง€ ์•Š๋„๋ก None ์ฒ˜๋ฆฌ
478
+ # ์•„๋ž˜ ์ˆœ์„œ: url1, url2, url3, lecture_content1, lecture_content2, lecture_content3, merged_content
479
+ # URL ํ…์ŠคํŠธ๋ฐ•์Šค๏ฟฝ๏ฟฝ ์—…๋ฐ์ดํŠธ ์—†์ด ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด None ๋ฐ˜ํ™˜
480
+ None, None, None, merged_content]
481
  )
482
 
483
+ # ๋ชจ๋“ˆ2: ๊ฐ•์˜ ๋‚ด์šฉ ๊ฐ€์ ธ์˜ค๊ธฐ (ํƒ€์ดํ‹€ ์ˆ˜์ •)
484
+ with gr.Blocks() as additional_demo:
485
+ gr.Markdown("## ๊ฐ•์˜ ๋‚ด์šฉ ๊ฐ€์ ธ์˜ค๊ธฐ")
486
+ with gr.Row():
487
+ url1 = gr.Textbox(label="๊ฐ•์˜1 URL", elem_id="url1")
488
+ url2 = gr.Textbox(label="๊ฐ•์˜2 URL", elem_id="url2")
489
+ url3 = gr.Textbox(label="๊ฐ•์˜3 URL", elem_id="url3")
490
+ with gr.Row():
491
+ # ๊ฐœ๋ณ„ '๊ฐ•์˜ ๋‚ด์šฉ ๊ฐ€์ ธ์˜ค๊ธฐ' ๋ฒ„ํŠผ ์‚ญ์ œ (์š”์ฒญ์‚ฌํ•ญ์— ๋”ฐ๋ผ ์‚ญ์ œ)
492
+ pass
493
+ with gr.Row():
494
+ lecture_content1 = gr.Textbox(label="๊ฐ•์˜ ๋‚ด์šฉ", lines=10, elem_id="lecture_content1")
495
+ lecture_content2 = gr.Textbox(label="๊ฐ•์˜ ๋‚ด์šฉ", lines=10, elem_id="lecture_content2")
496
+ lecture_content3 = gr.Textbox(label="๊ฐ•์˜ ๋‚ด์šฉ", lines=10, elem_id="lecture_content3")
497
+ with gr.Row():
498
+ copy_btn1 = gr.Button("๊ฐ•์˜ ๋‚ด์šฉ ๋ณต์‚ฌํ•˜๊ธฐ", elem_id="copy_btn1")
499
+ copy_btn2 = gr.Button("๊ฐ•์˜ ๋‚ด์šฉ ๋ณต์‚ฌํ•˜๊ธฐ", elem_id="copy_btn2")
500
+ copy_btn3 = gr.Button("๊ฐ•์˜ ๋‚ด์šฉ ๋ณต์‚ฌํ•˜๊ธฐ", elem_id="copy_btn3")
501
+ with gr.Row():
502
+ copy_result1 = gr.Textbox(label="๊ฐ•์˜ ๋‚ด์šฉ ๋ณต์‚ฌํ•˜๊ธฐ ๊ฒฐ๊ณผ", interactive=False, elem_id="copy_result1")
503
+ copy_result2 = gr.Textbox(label="๊ฐ•์˜ ๋‚ด์šฉ ๋ณต์‚ฌํ•˜๊ธฐ ๊ฒฐ๊ณผ", interactive=False, elem_id="copy_result2")
504
+ copy_result3 = gr.Textbox(label="๊ฐ•์˜ ๋‚ด์šฉ ๋ณต์‚ฌํ•˜๊ธฐ ๊ฒฐ๊ณผ", interactive=False, elem_id="copy_result3")
505
+
506
+ custom_script = """
507
+ <script>
508
+ function setupCopy(copyBtnId, textBoxId, resultBoxId) {
509
+ const copyBtn = document.getElementById(copyBtnId);
510
+ if (!copyBtn) {
511
+ console.error("๋ฒ„ํŠผ " + copyBtnId + "๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.");
512
+ return;
513
+ }
514
+ copyBtn.addEventListener("click", function(){
515
+ const textBoxElem = document.getElementById(textBoxId);
516
+ const resultBoxElem = document.getElementById(resultBoxId);
517
+ if(textBoxElem && resultBoxElem) {
518
+ const textarea = textBoxElem.querySelector("textarea");
519
+ const resultTextarea = resultBoxElem.querySelector("textarea");
520
+ if(textarea && resultTextarea) {
521
+ var text = textarea.value;
522
+ if(text.trim() === ""){
523
+ resultTextarea.value = "๋ณต์‚ฌํ•  ๋‚ด์šฉ์ด ์—†์Šต๋‹ˆ๋‹ค.";
524
+ } else {
525
+ navigator.clipboard.writeText(text).then(function(){
526
+ resultTextarea.value = "๋ณต์‚ฌ์™„๋ฃŒ";
527
+ }, function(err){
528
+ resultTextarea.value = "๋ณต์‚ฌ ์‹คํŒจ";
529
+ });
530
+ }
531
+ }
532
+ }
533
+ });
534
+ }
535
+ document.addEventListener("DOMContentLoaded", function(){
536
+ setupCopy("copy_btn1", "lecture_content1", "copy_result1");
537
+ setupCopy("copy_btn2", "lecture_content2", "copy_result2");
538
+ setupCopy("copy_btn3", "lecture_content3", "copy_result3");
539
+ });
540
+ </script>
541
+ """
542
+ gr.HTML(custom_script)
543
+ gr.Markdown("๋””๋ฒ„๊น… ๋ชจ๋“œ ํ™œ์„ฑํ™”๋จ: ๋กœ๊ทธ๊ฐ€ ์ฝ˜์†”์— ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.")
544
+
545
+ # ๋ชจ๋“ˆ3์€ ์œ„์—์„œ ์ •์˜๋œ merge_demo ์‚ฌ์šฉ
546
  additional_demo.render()
547
  merge_demo.render()
548