Rathapoom commited on
Commit
b26c976
·
verified ·
1 Parent(s): 93b0fe2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +740 -34
app.py CHANGED
@@ -1602,6 +1602,397 @@ def show_story_progress():
1602
  </div>
1603
  """, unsafe_allow_html=True)
1604
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1605
  def show_story_ending_options():
1606
  """Display story ending options and guidance"""
1607
  if len(st.session_state.story) >= 10: # Show options when story is long enough
@@ -2566,50 +2957,365 @@ def show_completion_options():
2566
  """, unsafe_allow_html=True)
2567
 
2568
  # Show statistics
2569
- metrics_col1, metrics_col2 = st.columns(2)
2570
- with metrics_col1:
2571
- st.metric(
2572
- "จำนวนประโยคทั้งหมด",
2573
- len(st.session_state.story),
2574
- help="จำนวนประโยคในเรื่องทั้งหมด"
2575
- )
2576
- st.metric(
2577
- "คำศัพท์ที่ใช้",
2578
- len(st.session_state.stats['vocabulary_used']),
2579
- help="จำนวนคำศัพท์ที่ไม่ซ้ำกัน"
2580
- )
2581
 
2582
- with metrics_col2:
2583
- st.metric(
2584
- "คะแนนรวม",
2585
- st.session_state.points['total'],
2586
- help="คะแนนรวมที่ได้รับ"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2587
  )
2588
- st.metric(
2589
- "ความแม่นยำ",
2590
- f"{st.session_state.stats['accuracy_rate']:.1f}%",
2591
- help="อัตราการเขียนถูกต้อง"
 
 
 
2592
  )
2593
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2594
  # Save options
2595
- st.markdown("### 🎯 ต้องการทำอะไรต่อ?")
2596
- save_completed_story()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2597
 
2598
  # New story option
2599
  if st.button("🔄 เริ่มเรื่องใหม่",
2600
- key="new_story_button",
2601
  use_container_width=True):
2602
- if st.checkbox("✅ ยืนยันการเริ่มใหม่", key="confirm_reset"):
2603
- st.warning("การเริ่มใหม่จะลบเรื่องราวปัจจุบันทั้งหมด")
2604
- if st.button("🔄 ยืนยันการเริ่มใหม่",
2605
- key="final_confirm_reset",
2606
- use_container_width=True):
2607
- reset_story()
2608
- st.rerun()
2609
-
2610
  except Exception as e:
2611
- logging.error(f"Error showing completion options: {str(e)}")
2612
- st.error("เกิดข้อผิดพลาดในการแสดงตัวเลือกหลังจบเรื่อง")
2613
 
2614
  def show_save_dialog():
2615
  """Display save options dialog"""
 
1602
  </div>
1603
  """, unsafe_allow_html=True)
1604
 
1605
+ def generate_story_summary(story_entries: List[dict]) -> str:
1606
+ """Generate a concise summary of the story for the stitching process"""
1607
+ try:
1608
+ # Extract main story content
1609
+ story_text = []
1610
+ for entry in story_entries:
1611
+ if entry.get('content'):
1612
+ text = entry['content'].strip()
1613
+ if text.endswith('.'):
1614
+ text = text[:-1] # Remove trailing period for better concatenation
1615
+ story_text.append(text)
1616
+
1617
+ story_summary = '. '.join(story_text) + '.'
1618
+ return story_summary
1619
+
1620
+ except Exception as e:
1621
+ logging.error(f"Error generating story summary: {str(e)}")
1622
+ return "Error creating story summary."
1623
+
1624
+ def stitch_story(raw_story: List[dict], theme_id: str, level: str) -> Dict[str, str]:
1625
+ """Create a polished, coherent version of the story with Thai translation"""
1626
+ try:
1627
+ # Get theme details for context
1628
+ theme = story_themes.get(theme_id, {})
1629
+ theme_context = f"Theme: {theme.get('name_en', 'General')} - {theme.get('description_en', '')}"
1630
+
1631
+ # Get story summary
1632
+ story_summary = generate_story_summary(raw_story)
1633
+
1634
+ # Create level-appropriate instructions
1635
+ level_context = {
1636
+ 'Beginner': {
1637
+ 'instructions': """
1638
+ Create a simple, clear narrative using:
1639
+ - Basic vocabulary
1640
+ - Short, straightforward sentences
1641
+ - Present tense
1642
+ - Clear transitions
1643
+ Maintain the original story's key points but make it flow smoothly.
1644
+ """,
1645
+ 'max_tokens': 500,
1646
+ 'temperature': 0.7
1647
+ },
1648
+ 'Intermediate': {
1649
+ 'instructions': """
1650
+ Create an engaging narrative using:
1651
+ - Grade-appropriate vocabulary
1652
+ - Mix of simple and compound sentences
1653
+ - Present and past tense
1654
+ - Natural transitions
1655
+ Preserve the original story's elements while enhancing the flow.
1656
+ """,
1657
+ 'max_tokens': 700,
1658
+ 'temperature': 0.7
1659
+ },
1660
+ 'Advanced': {
1661
+ 'instructions': """
1662
+ Create a sophisticated narrative using:
1663
+ - Rich vocabulary
1664
+ - Varied sentence structures
1665
+ - Multiple tenses
1666
+ - Elegant transitions
1667
+ Maintain the story's essence while adding literary flourish.
1668
+ """,
1669
+ 'max_tokens': 1000,
1670
+ 'temperature': 0.8
1671
+ }
1672
+ }
1673
+
1674
+ level_settings = level_context[level]
1675
+
1676
+ # Generate polished English version
1677
+ response = client.chat.completions.create(
1678
+ model="gpt-4",
1679
+ messages=[
1680
+ {
1681
+ "role": "system",
1682
+ "content": f"""
1683
+ You are a professional children's story editor.
1684
+ {level_settings['instructions']}
1685
+ Context: {theme_context}
1686
+
1687
+ Task: Create a polished, coherent version of this story while:
1688
+ 1. Maintaining the original plot points
1689
+ 2. Improving flow and transitions
1690
+ 3. Adding appropriate descriptive elements
1691
+ 4. Making the narrative more engaging
1692
+ 5. Keeping the language level appropriate for {level} students
1693
+ """
1694
+ },
1695
+ {
1696
+ "role": "user",
1697
+ "content": f"Original story:\n{story_summary}\n\nCreate a polished version:"
1698
+ }
1699
+ ],
1700
+ max_tokens=level_settings['max_tokens'],
1701
+ temperature=level_settings['temperature']
1702
+ )
1703
+
1704
+ polished_english = response.choices[0].message.content.strip()
1705
+
1706
+ # Generate Thai translation
1707
+ translation_response = client.chat.completions.create(
1708
+ model="gpt-4",
1709
+ messages=[
1710
+ {
1711
+ "role": "system",
1712
+ "content": """
1713
+ You are a professional Thai-English translator specializing in children's literature.
1714
+ Create a natural, flowing Thai translation that:
1715
+ 1. Captures the story's meaning and emotion
1716
+ 2. Uses appropriate Thai language for the target age group
1717
+ 3. Maintains cultural relevance
1718
+ 4. Reads naturally in Thai
1719
+ """
1720
+ },
1721
+ {
1722
+ "role": "user",
1723
+ "content": f"Translate this story to Thai:\n{polished_english}"
1724
+ }
1725
+ ],
1726
+ max_tokens=1000,
1727
+ temperature=0.7
1728
+ )
1729
+
1730
+ thai_translation = translation_response.choices[0].message.content.strip()
1731
+
1732
+ return {
1733
+ 'original': story_summary,
1734
+ 'polished_english': polished_english,
1735
+ 'thai_translation': thai_translation
1736
+ }
1737
+
1738
+ except Exception as e:
1739
+ logging.error(f"Error in story stitching: {str(e)}")
1740
+ raise
1741
+
1742
+ def show_stitched_story(story_data: Dict[str, str]):
1743
+ """Display the stitched story with translation"""
1744
+ try:
1745
+ st.markdown("""
1746
+ <div style="
1747
+ background-color: #f8f9fa;
1748
+ padding: 20px;
1749
+ border-radius: 10px;
1750
+ margin: 20px 0;
1751
+ border: 2px solid #4caf50;
1752
+ ">
1753
+ <h3 style="color: #2e7d32; text-align: center; margin-bottom: 20px;">
1754
+ 📖 Your Polished Story | เรื่องราวฉบับสมบูรณ์
1755
+ </h3>
1756
+
1757
+ <div style="
1758
+ background-color: white;
1759
+ padding: 15px;
1760
+ border-radius: 8px;
1761
+ margin-bottom: 15px;
1762
+ ">
1763
+ <h4 style="color: #1565c0;">English Version</h4>
1764
+ <p style="color: #333; font-size: 1.1em; line-height: 1.6;">
1765
+ {story_data['polished_english']}
1766
+ </p>
1767
+ </div>
1768
+
1769
+ <div style="
1770
+ background-color: white;
1771
+ padding: 15px;
1772
+ border-radius: 8px;
1773
+ ">
1774
+ <h4 style="color: #1565c0;">ฉบับภาษาไทย</h4>
1775
+ <p style="color: #333; font-size: 1.1em; line-height: 1.6;">
1776
+ {story_data['thai_translation']}
1777
+ </p>
1778
+ </div>
1779
+ </div>
1780
+ """, unsafe_allow_html=True)
1781
+
1782
+ # Save options
1783
+ st.markdown("### 💾 บันทึกเรื่องราวฉบับสมบูรณ์")
1784
+ save_col1, save_col2 = st.columns(2)
1785
+
1786
+ with save_col1:
1787
+ if st.button("📥 บันทึกเป็น PDF",
1788
+ key="save_stitched_pdf",
1789
+ use_container_width=True):
1790
+ pdf_data = create_bilingual_story_pdf(story_data)
1791
+ st.download_button(
1792
+ "ดาวน์โหลด PDF",
1793
+ data=pdf_data,
1794
+ file_name=f"my_story_{datetime.now().strftime('%Y%m%d_%H%M')}.pdf",
1795
+ mime="application/pdf",
1796
+ key="download_stitched_pdf"
1797
+ )
1798
+
1799
+ with save_col2:
1800
+ if st.button("💾 บันทึกข้อความ",
1801
+ key="save_stitched_text",
1802
+ use_container_width=True):
1803
+ text_data = json.dumps(story_data, ensure_ascii=False, indent=2)
1804
+ st.download_button(
1805
+ "ดาวน์โหลดข้อความ",
1806
+ data=text_data,
1807
+ file_name=f"my_story_{datetime.now().strftime('%Y%m%d_%H%M')}.json",
1808
+ mime="application/json",
1809
+ key="download_stitched_text"
1810
+ )
1811
+
1812
+ except Exception as e:
1813
+ logging.error(f"Error showing stitched story: {str(e)}")
1814
+ st.error("เกิดข้อผิดพลาดในการแสดงเรื่องราวฉบับสมบูรณ์")
1815
+
1816
+ def create_bilingual_story_pdf(story_data: Dict[str, str]) -> bytes:
1817
+ """Create a PDF with both English and Thai versions of the story"""
1818
+ try:
1819
+ buffer = io.BytesIO()
1820
+ doc = SimpleDocTemplate(
1821
+ buffer,
1822
+ pagesize=A4,
1823
+ rightMargin=72,
1824
+ leftMargin=72,
1825
+ topMargin=72,
1826
+ bottomMargin=72
1827
+ )
1828
+
1829
+ # Create styles
1830
+ styles = getSampleStyleSheet()
1831
+ title_style = ParagraphStyle(
1832
+ 'CustomTitle',
1833
+ parent=styles['Title'],
1834
+ fontSize=24,
1835
+ spaceAfter=30,
1836
+ alignment=1 # Center alignment
1837
+ )
1838
+ heading_style = ParagraphStyle(
1839
+ 'CustomHeading',
1840
+ parent=styles['Heading1'],
1841
+ fontSize=18,
1842
+ spaceAfter=12,
1843
+ textColor=colors.blue
1844
+ )
1845
+ body_style = ParagraphStyle(
1846
+ 'CustomBody',
1847
+ parent=styles['Normal'],
1848
+ fontSize=12,
1849
+ spaceBefore=6,
1850
+ spaceAfter=6,
1851
+ leading=16
1852
+ )
1853
+
1854
+ # Create story elements
1855
+ elements = []
1856
+
1857
+ # Add title
1858
+ elements.append(Paragraph("My Story - JoyStory", title_style))
1859
+ elements.append(Spacer(1, 20))
1860
+
1861
+ # Add English version
1862
+ elements.append(Paragraph("English Version", heading_style))
1863
+ elements.append(Paragraph(story_data['polished_english'], body_style))
1864
+ elements.append(Spacer(1, 20))
1865
+
1866
+ # Add Thai version
1867
+ elements.append(Paragraph("ฉบับภาษาไทย", heading_style))
1868
+ elements.append(Paragraph(story_data['thai_translation'], body_style))
1869
+
1870
+ # Build PDF
1871
+ doc.build(elements)
1872
+ pdf = buffer.getvalue()
1873
+ buffer.close()
1874
+
1875
+ return pdf
1876
+
1877
+ except Exception as e:
1878
+ logging.error(f"Error creating bilingual PDF: {str(e)}")
1879
+ raise
1880
+
1881
+ def show_story_stats():
1882
+ """Display comprehensive story statistics"""
1883
+ try:
1884
+ st.markdown("""
1885
+ <div style="
1886
+ background-color: #f3e5f5;
1887
+ padding: 20px;
1888
+ border-radius: 10px;
1889
+ margin: 20px 0;
1890
+ ">
1891
+ <h3 style="color: #6a1b9a; margin-bottom: 15px; text-align: center;">
1892
+ 📊 สถิติการเขียนเรื่องราว
1893
+ </h3>
1894
+ """, unsafe_allow_html=True)
1895
+
1896
+ # Basic statistics in 2 columns
1897
+ col1, col2 = st.columns(2)
1898
+
1899
+ with col1:
1900
+ st.metric(
1901
+ "จำนวนประโยคทั้งหมด",
1902
+ len(st.session_state.story),
1903
+ help="จำนวนประโยคในเรื่องทั้งหมด"
1904
+ )
1905
+ st.metric(
1906
+ "คำศัพท์ที่ใช้",
1907
+ len(st.session_state.stats['vocabulary_used']),
1908
+ help="จำนวนคำศัพท์ที่ไม่ซ้ำกัน"
1909
+ )
1910
+ st.metric(
1911
+ "ประโยคที่ถูกต้องแล้ว",
1912
+ st.session_state.stats['correct_first_try'],
1913
+ help="จำนวนประโยคที่เขียนถูกต้องตั้งแต่ครั้งแรก"
1914
+ )
1915
+
1916
+ with col2:
1917
+ st.metric(
1918
+ "คะแนนรวม",
1919
+ st.session_state.points['total'],
1920
+ help="คะแนนรวมที่ได้รับ"
1921
+ )
1922
+ st.metric(
1923
+ "ความแม่นยำ",
1924
+ f"{st.session_state.stats['accuracy_rate']:.1f}%",
1925
+ help="อัตราการเขียนถูกต้อง"
1926
+ )
1927
+ st.metric(
1928
+ "Streak สูงสุด",
1929
+ st.session_state.points['max_streak'],
1930
+ help="จำนวนประโยคถูกต้องติดต่อกันมากที่สุด"
1931
+ )
1932
+
1933
+ # Show achievements
1934
+ if st.session_state.achievements:
1935
+ st.markdown("""
1936
+ <h4 style="color: #6a1b9a; margin: 20px 0 10px 0;">
1937
+ 🏆 ความสำเร็จที่ได้รับ
1938
+ </h4>
1939
+ """, unsafe_allow_html=True)
1940
+
1941
+ for achievement in st.session_state.achievements:
1942
+ st.success(achievement)
1943
+
1944
+ # Show writing progress details
1945
+ st.markdown("""
1946
+ <h4 style="color: #6a1b9a; margin: 20px 0 10px 0;">
1947
+ 📝 รายละเอียดการเขียน
1948
+ </h4>
1949
+ """, unsafe_allow_html=True)
1950
+
1951
+ details_col1, details_col2 = st.columns(2)
1952
+
1953
+ with details_col1:
1954
+ # Story composition metrics
1955
+ st.markdown("##### 📖 องค์ประกอบเรื่อง")
1956
+ avg_sentence_length = st.session_state.stats.get('average_sentence_length', 0)
1957
+ st.markdown(f"""
1958
+ - ความยาวประโยคเฉลี่ย: {avg_sentence_length:.1f} คำ
1959
+ - จำนวนคำทั้งหมด: {st.session_state.stats.get('total_words', 0)} คำ
1960
+ - การแก้ไข: {st.session_state.stats.get('corrections_made', 0)} ครั้ง
1961
+ """)
1962
+
1963
+ with details_col2:
1964
+ # Time and progress metrics
1965
+ st.markdown("##### ⏱️ เวลาและความก้าวหน้า")
1966
+ session_duration = st.session_state.stats.get('session_duration', 0)
1967
+ duration_minutes = session_duration / 60
1968
+ st.markdown(f"""
1969
+ - เวลาที่ใช้: {duration_minutes:.1f} นาที
1970
+ - ความก้าวหน้า: {min(len(st.session_state.story) * 5, 100)}%
1971
+ - สถานะ: {"จบเรื่องแล้ว" if st.session_state.story_completed else "กำลังเขีย��"}
1972
+ """)
1973
+
1974
+ # Show vocabulary usage
1975
+ if st.session_state.stats['vocabulary_used']:
1976
+ with st.expander("📚 คำศัพท์ที่ใช้"):
1977
+ vocab_list = sorted(list(st.session_state.stats['vocabulary_used']))
1978
+ st.markdown(f"""
1979
+ <div style="
1980
+ background-color: white;
1981
+ padding: 10px;
1982
+ border-radius: 5px;
1983
+ max-height: 200px;
1984
+ overflow-y: auto;
1985
+ ">
1986
+ {', '.join(vocab_list)}
1987
+ </div>
1988
+ """, unsafe_allow_html=True)
1989
+
1990
+ st.markdown("</div>", unsafe_allow_html=True)
1991
+
1992
+ except Exception as e:
1993
+ logging.error(f"Error showing story stats: {str(e)}")
1994
+ st.error("เกิดข้อผิดพลาดในการแสดงสถิติ")
1995
+
1996
  def show_story_ending_options():
1997
  """Display story ending options and guidance"""
1998
  if len(st.session_state.story) >= 10: # Show options when story is long enough
 
2957
  """, unsafe_allow_html=True)
2958
 
2959
  # Show statistics
2960
+ show_story_stats()
 
 
 
 
 
 
 
 
 
 
 
2961
 
2962
+ # Offer story stitching option
2963
+ st.markdown("### ✨ ต้องการให้ AI ช่วยเรียบเรียงเรื่องราวให้สมบูรณ์ขึ้นไหม?")
2964
+
2965
+ if st.button("🎨 เรียบเรียงเรื่องราว",
2966
+ key="stitch_story_button",
2967
+ use_container_width=True):
2968
+ with st.spinner("กำลังเรียบเรียงเรื่องราว..."):
2969
+ try:
2970
+ stitched_story = stitch_story(
2971
+ st.session_state.story,
2972
+ st.session_state.current_theme,
2973
+ st.session_state.level
2974
+ )
2975
+ show_stitched_story(stitched_story)
2976
+ except Exception as e:
2977
+ logging.error(f"Error in story stitching: {str(e)}")
2978
+ st.error("เกิดข้อผิดพลาดในการเรียบเรียงเรื่องราว กรุณาลองใหม่อีกครั้ง")
2979
+
2980
+ # Original save options
2981
+ st.markdown("### 💾 บันทึกเรื่องราวต้นฉบับ")
2982
+ save_col1, save_col2 = st.columns(2)
2983
+
2984
+ with save_col1:
2985
+ if st.button("📑 บันทึกเป็น PDF",
2986
+ key="save_original_pdf",
2987
+ use_container_width=True):
2988
+ pdf_data = create_story_pdf()
2989
+ st.download_button(
2990
+ "ดาวน์โหลด PDF",
2991
+ data=pdf_data,
2992
+ file_name=f"original_story_{datetime.now().strftime('%Y%m%d_%H%M')}.pdf",
2993
+ mime="application/pdf",
2994
+ key="download_original_pdf"
2995
+ )
2996
+
2997
+ with save_col2:
2998
+ if st.button("🔄 เริ่มเรื่องใหม่",
2999
+ key="new_story_button",
3000
+ use_container_width=True):
3001
+ if st.checkbox("✅ ยืนยันการเริ่มใหม่",
3002
+ key="confirm_new_story"):
3003
+ reset_story()
3004
+ st.rerun()
3005
+
3006
+ except Exception as e:
3007
+ logging.error(f"Error showing completion options: {str(e)}")
3008
+ st.error("เกิดข้อผิดพลาดในการแสดงตัวเลือกหลังจบเรื่อง")
3009
+
3010
+ def show_story_stitching_options():
3011
+ """Display story stitching options and handle the flow"""
3012
+ try:
3013
+ st.markdown("""
3014
+ <div style="
3015
+ background-color: #e3f2fd;
3016
+ padding: 20px;
3017
+ border-radius: 10px;
3018
+ margin: 20px 0;
3019
+ ">
3020
+ <h3 style="color: #1565c0; margin-bottom: 15px;">
3021
+ ✨ เรียบเรียงเรื่องราวให้สมบูรณ์
3022
+ </h3>
3023
+ <p style="color: #333;">
3024
+ AI จะช่วย:
3025
+ - ปรับแต่งการเชื่อมประโยคให้ลื่นไหล
3026
+ - เพิ่มรายละเอียดที่น่าสนใจ
3027
+ - แปลเป็นภาษาไทย
3028
+ - รักษาเนื้อเรื่องและความคิดสร้างสรรค์ของคุณไว้
3029
+ </p>
3030
+ </div>
3031
+ """, unsafe_allow_html=True)
3032
+
3033
+ col1, col2 = st.columns(2)
3034
+
3035
+ with col1:
3036
+ style_option = st.selectbox(
3037
+ "เลือกรูปแบบการเล่าเรื่อง:",
3038
+ options=[
3039
+ "Classic Fairytale - นิทานแบบคลาสสิก",
3040
+ "Modern Adventure - การผจญภัยสมัยใหม่",
3041
+ "Poetic Style - แบบกวีนิพนธ์",
3042
+ "Simple and Clear - เรียบง่ายและชัดเจน"
3043
+ ],
3044
+ key="story_style_selector"
3045
  )
3046
+
3047
+ with col2:
3048
+ detail_level = st.select_slider(
3049
+ "ระดับรายละเอียด:",
3050
+ options=["น้อย", "ปานกลาง", "มาก"],
3051
+ value="ปานกลาง",
3052
+ key="detail_level_selector"
3053
  )
3054
 
3055
+ if st.button("🎨 เริ่มเรียบเรียงเรื่องราว",
3056
+ key="start_stitching",
3057
+ use_container_width=True):
3058
+ with st.spinner("กำลังเรียบเรียงเรื่องราว..."):
3059
+ try:
3060
+ stitched_story = generate_stitched_story(
3061
+ story=st.session_state.story,
3062
+ style=style_option,
3063
+ detail_level=detail_level,
3064
+ theme=st.session_state.current_theme,
3065
+ level=st.session_state.level
3066
+ )
3067
+
3068
+ # Save stitched story to session state
3069
+ st.session_state.stitched_story = stitched_story
3070
+
3071
+ # Show the result
3072
+ show_stitched_result(stitched_story)
3073
+
3074
+ except Exception as e:
3075
+ logging.error(f"Error in story stitching: {str(e)}")
3076
+ st.error("เกิดข้อผิดพลาดในการเรียบเรียงเรื่องราว กรุณาลองใหม่อีกครั้ง")
3077
+
3078
+ except Exception as e:
3079
+ logging.error(f"Error showing stitching options: {str(e)}")
3080
+ st.error("เกิดข้อผิดพลาดในการแสดงตัวเลือกการเรียบเรียง")
3081
+
3082
+ def generate_stitched_story(story: List[dict], style: str, detail_level: str, theme: str, level: str) -> Dict[str, str]:
3083
+ """Generate a polished version of the story based on selected style and detail level"""
3084
+ try:
3085
+ # Convert detail level to English
3086
+ detail_map = {
3087
+ "น้อย": "minimal",
3088
+ "ปานกลาง": "moderate",
3089
+ "มาก": "detailed"
3090
+ }
3091
+ detail_level_en = detail_map.get(detail_level, "moderate")
3092
+
3093
+ # Extract style name
3094
+ style_name = style.split(" - ")[0]
3095
+
3096
+ # Create style-specific instructions
3097
+ style_instructions = {
3098
+ "Classic Fairytale": """
3099
+ Create a classic fairytale style with:
3100
+ - Traditional opening and closing phrases
3101
+ - Magical and whimsical elements
3102
+ - Clear moral or lesson
3103
+ - Flowing, storybook language
3104
+ """,
3105
+ "Modern Adventure": """
3106
+ Create a contemporary adventure style with:
3107
+ - Dynamic pacing
3108
+ - Modern settings and references
3109
+ - Engaging action sequences
3110
+ - Relatable characters
3111
+ """,
3112
+ "Poetic Style": """
3113
+ Create a poetic narrative style with:
3114
+ - Rich imagery and metaphors
3115
+ - Rhythmic language
3116
+ - Evocative descriptions
3117
+ - Artistic expression
3118
+ """,
3119
+ "Simple and Clear": """
3120
+ Create a clear, straightforward style with:
3121
+ - Direct language
3122
+ - Clear sequence of events
3123
+ - Focused storytelling
3124
+ - Easy-to-follow structure
3125
+ """
3126
+ }
3127
+
3128
+ # Create detail level instructions
3129
+ detail_instructions = {
3130
+ "minimal": "Keep descriptions concise and focus on key events.",
3131
+ "moderate": "Balance description and action with moderate detail.",
3132
+ "detailed": "Include rich descriptions and elaborate on scenes and characters."
3133
+ }
3134
+
3135
+ # Generate polished version
3136
+ response = client.chat.completions.create(
3137
+ model="gpt-4",
3138
+ messages=[
3139
+ {
3140
+ "role": "system",
3141
+ "content": f"""
3142
+ You are a professional children's story editor and translator.
3143
+
3144
+ Style Guidelines:
3145
+ {style_instructions[style_name]}
3146
+
3147
+ Detail Level:
3148
+ {detail_instructions[detail_level_en]}
3149
+
3150
+ Educational Level: {level}
3151
+
3152
+ Create a polished version that:
3153
+ 1. Maintains the original story's core elements
3154
+ 2. Adapts to the requested style
3155
+ 3. Provides appropriate detail level
3156
+ 4. Ensures age-appropriate language
3157
+ 5. Creates a cohesive narrative flow
3158
+ """
3159
+ },
3160
+ {
3161
+ "role": "user",
3162
+ "content": f"Original story:\n{generate_story_summary(story)}\n\nCreate a polished version:"
3163
+ }
3164
+ ],
3165
+ max_tokens=1500,
3166
+ temperature=0.7
3167
+ )
3168
+
3169
+ polished_english = response.choices[0].message.content.strip()
3170
+
3171
+ # Generate Thai translation with matching style
3172
+ translation_response = client.chat.completions.create(
3173
+ model="gpt-4",
3174
+ messages=[
3175
+ {
3176
+ "role": "system",
3177
+ "content": f"""
3178
+ You are a professional Thai translator specializing in children's literature.
3179
+
3180
+ Create a Thai translation that:
3181
+ 1. Matches the {style_name} style
3182
+ 2. Maintains the same detail level ({detail_level_en})
3183
+ 3. Uses natural, flowing Thai language
3184
+ 4. Preserves the story's tone and feeling
3185
+ 5. Adapts cultural elements appropriately
3186
+ """
3187
+ },
3188
+ {
3189
+ "role": "user",
3190
+ "content": f"Translate this story to Thai:\n{polished_english}"
3191
+ }
3192
+ ],
3193
+ max_tokens=1500,
3194
+ temperature=0.7
3195
+ )
3196
+
3197
+ thai_translation = translation_response.choices[0].message.content.strip()
3198
+
3199
+ return {
3200
+ 'original': generate_story_summary(story),
3201
+ 'polished_english': polished_english,
3202
+ 'thai_translation': thai_translation,
3203
+ 'style': style_name,
3204
+ 'detail_level': detail_level_en
3205
+ }
3206
+
3207
+ except Exception as e:
3208
+ logging.error(f"Error generating stitched story: {str(e)}")
3209
+ raise
3210
+
3211
+ def show_stitched_result(story_data: Dict[str, str]):
3212
+ """Display the stitched story result with enhanced formatting"""
3213
+ try:
3214
+ st.markdown("""
3215
+ <div style="
3216
+ background-color: #f8f9fa;
3217
+ padding: 20px;
3218
+ border-radius: 10px;
3219
+ margin: 20px 0;
3220
+ ">
3221
+ <h2 style="color: #1565c0; text-align: center; margin-bottom: 20px;">
3222
+ ✨ เรื่องราวฉบับสมบูรณ์ | Complete Story
3223
+ </h2>
3224
+
3225
+ <div style="
3226
+ background-color: white;
3227
+ padding: 20px;
3228
+ border-radius: 8px;
3229
+ margin-bottom: 20px;
3230
+ border: 1px solid #e0e0e0;
3231
+ ">
3232
+ <h3 style="color: #2e7d32; margin-bottom: 10px;">
3233
+ English Version
3234
+ </h3>
3235
+ <div style="
3236
+ color: #333;
3237
+ font-size: 1.1em;
3238
+ line-height: 1.6;
3239
+ white-space: pre-line;
3240
+ ">
3241
+ {story_data['polished_english']}
3242
+ </div>
3243
+ </div>
3244
+
3245
+ <div style="
3246
+ background-color: white;
3247
+ padding: 20px;
3248
+ border-radius: 8px;
3249
+ border: 1px solid #e0e0e0;
3250
+ ">
3251
+ <h3 style="color: #2e7d32; margin-bottom: 10px;">
3252
+ ฉบับภาษาไทย
3253
+ </h3>
3254
+ <div style="
3255
+ color: #333;
3256
+ font-size: 1.1em;
3257
+ line-height: 1.6;
3258
+ white-space: pre-line;
3259
+ ">
3260
+ {story_data['thai_translation']}
3261
+ </div>
3262
+ </div>
3263
+ </div>
3264
+ """, unsafe_allow_html=True)
3265
+
3266
  # Save options
3267
+ st.markdown("### 💾 บันทึกเรื่องราว")
3268
+
3269
+ save_col1, save_col2 = st.columns(2)
3270
+
3271
+ with save_col1:
3272
+ if st.button("📥 บันทึกเป็น PDF",
3273
+ key="save_final_pdf",
3274
+ use_container_width=True):
3275
+ try:
3276
+ pdf_data = create_bilingual_story_pdf(story_data)
3277
+ file_name = f"my_story_{datetime.now().strftime('%Y%m%d_%H%M')}.pdf"
3278
+ st.download_button(
3279
+ "ดาวน์โหลด PDF",
3280
+ data=pdf_data,
3281
+ file_name=file_name,
3282
+ mime="application/pdf",
3283
+ key="download_final_pdf"
3284
+ )
3285
+ except Exception as e:
3286
+ logging.error(f"Error saving PDF: {str(e)}")
3287
+ st.error("เกิดข้อผิดพลาดในการสร้างไฟล์ PDF")
3288
+
3289
+ with save_col2:
3290
+ if st.button("📝 บันทึกข้อความ",
3291
+ key="save_final_text",
3292
+ use_container_width=True):
3293
+ try:
3294
+ text_data = json.dumps(story_data, ensure_ascii=False, indent=2)
3295
+ file_name = f"my_story_{datetime.now().strftime('%Y%m%d_%H%M')}.json"
3296
+ st.download_button(
3297
+ "ดาวน์โหลดข้อความ",
3298
+ data=text_data,
3299
+ file_name=file_name,
3300
+ mime="application/json",
3301
+ key="download_final_text"
3302
+ )
3303
+ except Exception as e:
3304
+ logging.error(f"Error saving text: {str(e)}")
3305
+ st.error("เกิดข้อผิดพลาดในการบันทึกข้อความ")
3306
 
3307
  # New story option
3308
  if st.button("🔄 เริ่มเรื่องใหม่",
3309
+ key="new_story_after_stitch",
3310
  use_container_width=True):
3311
+ if st.checkbox("✅ ยืนยันการเริ่มใหม่",
3312
+ key="confirm_new_after_stitch"):
3313
+ reset_story()
3314
+ st.rerun()
3315
+
 
 
 
3316
  except Exception as e:
3317
+ logging.error(f"Error showing stitched result: {str(e)}")
3318
+ st.error("เกิดข้อผิดพลาดในการแสดงผลลัพธ์")
3319
 
3320
  def show_save_dialog():
3321
  """Display save options dialog"""