youngtsai commited on
Commit
c64380a
·
1 Parent(s): 1a8d8ed
Files changed (1) hide show
  1. app.py +63 -36
app.py CHANGED
@@ -6,6 +6,8 @@ from docx import Document
6
  import os
7
  from openai import OpenAI
8
  from groq import Groq
 
 
9
 
10
  from youtube_transcript_api import YouTubeTranscriptApi
11
  from youtube_transcript_api._errors import NoTranscriptFound
@@ -713,6 +715,12 @@ def generate_reading_passage(df_string):
713
 
714
  return reading_passage
715
 
 
 
 
 
 
 
716
  def get_mind_map(video_id, df_string, source):
717
  if source == "gcs":
718
  print("===get_mind_map on gcs===")
@@ -1025,6 +1033,18 @@ def generate_exam_fine_tune_result(password, exam_result_prompt , df_string_outp
1025
  ai_content = material.send_ai_request(OPEN_AI_CLIENT, request_payload)
1026
  return ai_content
1027
 
 
 
 
 
 
 
 
 
 
 
 
 
1028
  # ---- Chatbot ----
1029
  def respond(password, user_message, data, chat_history, socratic_mode=False):
1030
  verify_password(password)
@@ -1296,7 +1316,7 @@ def chat_with_groq(password, user_message, data, chat_history, socratic_mode=Fal
1296
  # 返回聊天历史和空字符串清空输入框
1297
  return "", chat_history
1298
 
1299
- def chat_with_youtube_transcript(password, youtube_id, thread_id, trascript, user_message, chat_history, socratic_mode=False):
1300
  verify_password(password)
1301
 
1302
  # 先計算 user_message 是否超過 500 個字
@@ -1304,6 +1324,11 @@ def chat_with_youtube_transcript(password, youtube_id, thread_id, trascript, use
1304
  error_msg = "你的訊息太長了,請縮短訊息長度至五百字以內"
1305
  raise gr.Error(error_msg)
1306
 
 
 
 
 
 
1307
  try:
1308
  assistant_id = "asst_kmvZLNkDUYaNkMNtZEAYxyPq"
1309
  client = OPEN_AI_CLIENT
@@ -1346,18 +1371,24 @@ def chat_with_youtube_transcript(password, youtube_id, thread_id, trascript, use
1346
  你是一個擅長資料分析跟影片教學的老師,user 為學生
1347
  如果是影片類型,不用解釋逐字稿格式,直接回答學生問題
1348
  socratic_mode = {socratic_mode}
1349
- 如果 socratic_mode = True,
1350
  - 請用蘇格拉底式的提問方式,引導學生思考,並且給予學生一些提示
 
1351
  - 不要直接給予答案,讓學生自己思考
1352
  - 但可以給予一些提示跟引導,例如給予影片的時間軸,讓學生自己去找答案
1353
  - 在你回答的開頭標註【蘇格拉底助教:{youtube_id} 】
1354
- 如果 socratic_mode = False,
1355
- - 直接回答學生問題
 
1356
  - 在你回答的開頭標註【一般學習精靈:{youtube_id} 】
 
1357
  如果學生問了一些問題你無法判斷,請告訴學生你無法判斷,並建議學生可以問其他問題
1358
- 或者你可以反問學生一些問題,幫助學生更好的理解資料
1359
- 如果學生的問題與資料文本無關,請告訴學生你無法回答超出範圍的問題
1360
- 最後只要是參考逐字稿資料,請在回答的最後標註【參考資料:(分):(秒)】
 
 
 
1361
  """
1362
 
1363
  # 创建线程
@@ -1371,7 +1402,7 @@ def chat_with_youtube_transcript(password, youtube_id, thread_id, trascript, use
1371
  client.beta.threads.messages.create(
1372
  thread_id=thread.id,
1373
  role="user",
1374
- content=user_message
1375
  )
1376
 
1377
  # 运行助手,生成响应
@@ -1580,6 +1611,8 @@ with gr.Blocks() as demo:
1580
  with gr.Column(scale=3):
1581
  with gr.Tab("文章模式"):
1582
  reading_passage = gr.Textbox(label="Reading Passage", lines=40)
 
 
1583
  with gr.Tab("重點"):
1584
  df_summarise = gr.Textbox(container=True, show_copy_button=True, lines=40)
1585
  with gr.Tab("問題"):
@@ -1675,33 +1708,17 @@ with gr.Blocks() as demo:
1675
  with gr.Column(scale=2):
1676
  # 生成對應不同模式的結果
1677
  exam_result_prompt = gr.Textbox(visible=False)
1678
- exam_result = gr.Textbox(label="初次生成結果", show_copy_button=True)
1679
  exam_result_fine_tune_prompt = gr.Textbox(label="根據結果,輸入你想更改的想法")
1680
  exam_result_fine_tune_btn = gr.Button("微調結果")
1681
  exam_result_fine_result = gr.Textbox(label="微調結果",show_copy_button=True)
1682
-
1683
- # 傳統模式
1684
- # send_button.click(
1685
- # respond,
1686
- # inputs=[msg, df_string_output, chatbot, socratic_mode_btn],
1687
- # outputs=[msg, chatbot]
1688
- # )
1689
- # # 连接按钮点击事件
1690
- # btn_1.click(respond, inputs=[btn_1, df_string_output, chatbot, socratic_mode_btn], outputs=[msg, chatbot])
1691
- # btn_2.click(respond, inputs=[btn_2, df_string_output, chatbot, socratic_mode_btn], outputs=[msg, chatbot])
1692
- # btn_3.click(respond, inputs=[btn_3, df_string_output, chatbot, socratic_mode_btn], outputs=[msg, chatbot])
1693
-
1694
- # chat_with_youtube_transcript
1695
- # send_button.click(
1696
- # chat_with_youtube_transcript,
1697
- # inputs=[password, video_id, thread_id, df_string_output, msg, chatbot, socratic_mode_btn],
1698
- # outputs=[msg, chatbot, thread_id]
1699
- # )
1700
- # chat_with_youtube_transcript
1701
-
1702
  # OPENAI 模式
1703
  send_button.click(
1704
- chat_with_youtube_transcript,
1705
  inputs=[password, video_id, thread_id, df_string_output, msg, chatbot, socratic_mode_btn],
1706
  outputs=[msg, chatbot, thread_id]
1707
  )
@@ -1710,8 +1727,6 @@ with gr.Blocks() as demo:
1710
  inputs=[password, openai_chatbot_audio_input],
1711
  outputs=[msg]
1712
  )
1713
-
1714
-
1715
  # GROQ 模式
1716
  groq_send_button.click(
1717
  chat_with_groq,
@@ -1725,20 +1740,19 @@ with gr.Blocks() as demo:
1725
  outputs=[jutor_msg, jutor_chatbot]
1726
  )
1727
 
1728
-
1729
  # 连接按钮点击事件
1730
  btn_1.click(
1731
- chat_with_youtube_transcript,
1732
  inputs=[password, video_id, thread_id, df_string_output, btn_1, chatbot, socratic_mode_btn],
1733
  outputs=[msg, chatbot, thread_id]
1734
  )
1735
  btn_2.click(
1736
- chat_with_youtube_transcript,
1737
  inputs=[password, video_id, thread_id, df_string_output, btn_2, chatbot, socratic_mode_btn],
1738
  outputs=[msg, chatbot, thread_id]
1739
  )
1740
  btn_3.click(
1741
- chat_with_youtube_transcript,
1742
  inputs=[password, video_id, thread_id, df_string_output, btn_3, chatbot, socratic_mode_btn],
1743
  outputs=[msg, chatbot, thread_id]
1744
  )
@@ -1792,6 +1806,13 @@ with gr.Blocks() as demo:
1792
  # 当输入网页链接时触发
1793
  # web_link.change(process_web_link, inputs=web_link, outputs=[btn_1, btn_2, btn_3, df_summarise, df_string_output])
1794
 
 
 
 
 
 
 
 
1795
  # 教師版 學習單
1796
  worksheet_content_btn.click(
1797
  on_generate_ai_content,
@@ -1815,6 +1836,12 @@ with gr.Blocks() as demo:
1815
  inputs=[password, exam_result_prompt, df_string_output, exam_result, exam_result_fine_tune_prompt],
1816
  outputs=[exam_result_fine_result]
1817
  )
 
 
 
 
 
 
1818
 
1819
  demo.load(
1820
  init_params,
 
6
  import os
7
  from openai import OpenAI
8
  from groq import Groq
9
+ from docx import Document
10
+ from gtts import gTTS
11
 
12
  from youtube_transcript_api import YouTubeTranscriptApi
13
  from youtube_transcript_api._errors import NoTranscriptFound
 
715
 
716
  return reading_passage
717
 
718
+ def text_to_speech(video_id, text):
719
+ tts = gTTS(text, lang='en')
720
+ filename = f'{video_id}_reading_passage.mp3'
721
+ tts.save(filename)
722
+ return filename
723
+
724
  def get_mind_map(video_id, df_string, source):
725
  if source == "gcs":
726
  print("===get_mind_map on gcs===")
 
1033
  ai_content = material.send_ai_request(OPEN_AI_CLIENT, request_payload)
1034
  return ai_content
1035
 
1036
+ def create_word(content):
1037
+ unique_filename = str(uuid.uuid4())
1038
+ word_file_path = f"/tmp/{unique_filename}.docx"
1039
+ doc = Document()
1040
+ doc.add_paragraph(content)
1041
+ doc.save(word_file_path)
1042
+ return word_file_path
1043
+
1044
+ def download_exam_result(content):
1045
+ word_path = create_word(content)
1046
+ return word_path
1047
+
1048
  # ---- Chatbot ----
1049
  def respond(password, user_message, data, chat_history, socratic_mode=False):
1050
  verify_password(password)
 
1316
  # 返回聊天历史和空字符串清空输入框
1317
  return "", chat_history
1318
 
1319
+ def chat_with_opan_ai_assistant(password, youtube_id, thread_id, trascript, user_message, chat_history, socratic_mode=False):
1320
  verify_password(password)
1321
 
1322
  # 先計算 user_message 是否超過 500 個字
 
1324
  error_msg = "你的訊息太長了,請縮短訊息長度至五百字以內"
1325
  raise gr.Error(error_msg)
1326
 
1327
+ # 如果 chat_history 超過 10 則訊息,直接 return "對話超過上限"
1328
+ if chat_history is not None and len(chat_history) > 10:
1329
+ error_msg = "此次對話超過上限"
1330
+ raise gr.Error(error_msg)
1331
+
1332
  try:
1333
  assistant_id = "asst_kmvZLNkDUYaNkMNtZEAYxyPq"
1334
  client = OPEN_AI_CLIENT
 
1371
  你是一個擅長資料分析跟影片教學的老師,user 為學生
1372
  如果是影片類型,不用解釋逐字稿格式,直接回答學生問題
1373
  socratic_mode = {socratic_mode}
1374
+ if socratic_mode is True,
1375
  - 請用蘇格拉底式的提問方式,引導學生思考,並且給予學生一些提示
1376
+ - 一次只問一個問題,字數在100字以內
1377
  - 不要直接給予答案,讓學生自己思考
1378
  - 但可以給予一些提示跟引導,例如給予影片的時間軸,讓學生自己去找答案
1379
  - 在你回答的開頭標註【蘇格拉底助教:{youtube_id} 】
1380
+
1381
+ if socratic_mode is False,
1382
+ - 直接回答學生問題,字數在100字以內
1383
  - 在你回答的開頭標註【一般學習精靈:{youtube_id} 】
1384
+
1385
  如果學生問了一些問題你無法判斷,請告訴學生你無法判斷,並建議學生可以問其他問題
1386
+ 或者你可以反問學生一些問題,幫助學生更好的理解資料,字數在100字以內
1387
+ 如果學生的問題與資料文本無關,請告訴學生你「無法回答超出範圍的問題」,並告訴他可以怎麼問什麼樣的問題(一個就好)
1388
+ 只要是參考逐字稿資料,請在回答的最後標註【參考資料:(分):(秒)】
1389
+ 請一定要用繁體中文回答 zh-TW,並用台灣人的口語表達
1390
+ 回答範圍一定要在逐字稿資料內,不要引用其他資料,請嚴格執行
1391
+ 並在重複問句後給予學生鼓勵,讓學生有學習的動力
1392
  """
1393
 
1394
  # 创建线程
 
1402
  client.beta.threads.messages.create(
1403
  thread_id=thread.id,
1404
  role="user",
1405
+ content=user_message + "(請一定要用繁體中文回答 zh-TW,並用台灣人的口語表達,回答時不要特別說明這是台灣人的語氣)"
1406
  )
1407
 
1408
  # 运行助手,生成响应
 
1611
  with gr.Column(scale=3):
1612
  with gr.Tab("文章模式"):
1613
  reading_passage = gr.Textbox(label="Reading Passage", lines=40)
1614
+ reading_passage_speak_button = gr.Button("Speak", visible=False)
1615
+ reading_passage_audio_output = gr.Audio(label="Audio Output", visible=False)
1616
  with gr.Tab("重點"):
1617
  df_summarise = gr.Textbox(container=True, show_copy_button=True, lines=40)
1618
  with gr.Tab("問題"):
 
1708
  with gr.Column(scale=2):
1709
  # 生成對應不同模式的結果
1710
  exam_result_prompt = gr.Textbox(visible=False)
1711
+ exam_result = gr.Textbox(label="初次生成結果", show_copy_button=True, interactive=True)
1712
  exam_result_fine_tune_prompt = gr.Textbox(label="根據結果,輸入你想更改的想法")
1713
  exam_result_fine_tune_btn = gr.Button("微調結果")
1714
  exam_result_fine_result = gr.Textbox(label="微調結果",show_copy_button=True)
1715
+
1716
+ download_exam_result_button = gr.Button("下载结果")
1717
+ exam_result_word_link = gr.File(label="Download Word")
1718
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1719
  # OPENAI 模式
1720
  send_button.click(
1721
+ chat_with_opan_ai_assistant,
1722
  inputs=[password, video_id, thread_id, df_string_output, msg, chatbot, socratic_mode_btn],
1723
  outputs=[msg, chatbot, thread_id]
1724
  )
 
1727
  inputs=[password, openai_chatbot_audio_input],
1728
  outputs=[msg]
1729
  )
 
 
1730
  # GROQ 模式
1731
  groq_send_button.click(
1732
  chat_with_groq,
 
1740
  outputs=[jutor_msg, jutor_chatbot]
1741
  )
1742
 
 
1743
  # 连接按钮点击事件
1744
  btn_1.click(
1745
+ chat_with_opan_ai_assistant,
1746
  inputs=[password, video_id, thread_id, df_string_output, btn_1, chatbot, socratic_mode_btn],
1747
  outputs=[msg, chatbot, thread_id]
1748
  )
1749
  btn_2.click(
1750
+ chat_with_opan_ai_assistant,
1751
  inputs=[password, video_id, thread_id, df_string_output, btn_2, chatbot, socratic_mode_btn],
1752
  outputs=[msg, chatbot, thread_id]
1753
  )
1754
  btn_3.click(
1755
+ chat_with_opan_ai_assistant,
1756
  inputs=[password, video_id, thread_id, df_string_output, btn_3, chatbot, socratic_mode_btn],
1757
  outputs=[msg, chatbot, thread_id]
1758
  )
 
1806
  # 当输入网页链接时触发
1807
  # web_link.change(process_web_link, inputs=web_link, outputs=[btn_1, btn_2, btn_3, df_summarise, df_string_output])
1808
 
1809
+ # 文章模式
1810
+ reading_passage_speak_button.click(
1811
+ text_to_speech,
1812
+ inputs=[video_id, reading_passage],
1813
+ outputs=reading_passage_audio_output
1814
+ )
1815
+
1816
  # 教師版 學習單
1817
  worksheet_content_btn.click(
1818
  on_generate_ai_content,
 
1836
  inputs=[password, exam_result_prompt, df_string_output, exam_result, exam_result_fine_tune_prompt],
1837
  outputs=[exam_result_fine_result]
1838
  )
1839
+ download_exam_result_button.click(
1840
+ download_exam_result,
1841
+ inputs=[exam_result],
1842
+ outputs=[exam_result_word_link]
1843
+ )
1844
+
1845
 
1846
  demo.load(
1847
  init_params,