Update app.py
Browse files
app.py
CHANGED
@@ -3,6 +3,16 @@ import json
|
|
3 |
import datetime
|
4 |
from openai import OpenAI
|
5 |
from typing import Dict, List, Set
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
|
7 |
# ระบบ Achievements
|
8 |
achievements_list = {
|
@@ -569,6 +579,119 @@ def update_achievements(text: str):
|
|
569 |
st.session_state.badges.append(badge)
|
570 |
st.success(f"🏆 Achievement Unlocked: {badge}!")
|
571 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
572 |
def reset_story():
|
573 |
"""Reset the story and related state variables."""
|
574 |
st.session_state.story = []
|
@@ -589,6 +712,16 @@ show_parent_guide() # Add parent guide right after welcome section
|
|
589 |
|
590 |
# Sidebar for settings
|
591 |
with st.sidebar:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
592 |
st.markdown("""
|
593 |
<div class="thai">
|
594 |
🎯 เลือกระดับการเรียนรู้
|
@@ -615,6 +748,7 @@ with st.sidebar:
|
|
615 |
if st.button("เริ่มเรื่องใหม่ | Start New Story"):
|
616 |
st.session_state.should_reset = True
|
617 |
st.rerun()
|
|
|
618 |
|
619 |
# Main content area
|
620 |
col1, col2 = st.columns([3, 1])
|
@@ -763,18 +897,37 @@ with col2:
|
|
763 |
|
764 |
# Save Story Button
|
765 |
if st.session_state.story:
|
766 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
767 |
story_data = {
|
768 |
'level': st.session_state.level,
|
769 |
-
'date': datetime.
|
770 |
'story': st.session_state.story,
|
771 |
-
'achievements': st.session_state.
|
772 |
-
'
|
773 |
-
'
|
|
|
|
|
|
|
|
|
|
|
774 |
}
|
775 |
st.download_button(
|
776 |
-
label="
|
777 |
data=json.dumps(story_data, indent=2),
|
778 |
-
file_name='
|
779 |
-
mime=
|
780 |
)
|
|
|
3 |
import datetime
|
4 |
from openai import OpenAI
|
5 |
from typing import Dict, List, Set
|
6 |
+
import io
|
7 |
+
from reportlab.lib import colors
|
8 |
+
from reportlab.lib.pagesizes import A4
|
9 |
+
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
|
10 |
+
from reportlab.lib.units import inch
|
11 |
+
from reportlab.pdfgen import canvas
|
12 |
+
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image
|
13 |
+
from reportlab.pdfbase import pdfmetrics
|
14 |
+
from reportlab.pdfbase.ttfonts import TTFont
|
15 |
+
from datetime import datetime
|
16 |
|
17 |
# ระบบ Achievements
|
18 |
achievements_list = {
|
|
|
579 |
st.session_state.badges.append(badge)
|
580 |
st.success(f"🏆 Achievement Unlocked: {badge}!")
|
581 |
|
582 |
+
def create_story_pdf():
|
583 |
+
"""สร้าง PDF จากเรื่องราวที่เขียน"""
|
584 |
+
buffer = io.BytesIO()
|
585 |
+
doc = SimpleDocTemplate(
|
586 |
+
buffer,
|
587 |
+
pagesize=A4,
|
588 |
+
rightMargin=72,
|
589 |
+
leftMargin=72,
|
590 |
+
topMargin=72,
|
591 |
+
bottomMargin=72
|
592 |
+
)
|
593 |
+
|
594 |
+
# สร้าง styles สำหรับ PDF
|
595 |
+
styles = getSampleStyleSheet()
|
596 |
+
title_style = ParagraphStyle(
|
597 |
+
'CustomTitle',
|
598 |
+
parent=styles['Heading1'],
|
599 |
+
fontSize=24,
|
600 |
+
spaceAfter=30,
|
601 |
+
alignment=1 # center
|
602 |
+
)
|
603 |
+
|
604 |
+
story_style = ParagraphStyle(
|
605 |
+
'StoryText',
|
606 |
+
parent=styles['Normal'],
|
607 |
+
fontSize=12,
|
608 |
+
spaceBefore=12,
|
609 |
+
spaceAfter=12,
|
610 |
+
leading=16
|
611 |
+
)
|
612 |
+
|
613 |
+
stats_style = ParagraphStyle(
|
614 |
+
'Stats',
|
615 |
+
parent=styles['Normal'],
|
616 |
+
fontSize=10,
|
617 |
+
textColor=colors.gray,
|
618 |
+
alignment=1
|
619 |
+
)
|
620 |
+
|
621 |
+
# สร้างเนื้อหา PDF
|
622 |
+
elements = []
|
623 |
+
|
624 |
+
# หน้าปก
|
625 |
+
elements.append(Paragraph("My English Story Adventure", title_style))
|
626 |
+
elements.append(Paragraph(
|
627 |
+
f"Created by: {st.session_state.get('player_name', 'Young Writer')}<br/>"
|
628 |
+
f"Date: {datetime.now().strftime('%B %d, %Y')}<br/>"
|
629 |
+
f"Level: {st.session_state.level}",
|
630 |
+
stats_style
|
631 |
+
))
|
632 |
+
elements.append(Spacer(1, 30))
|
633 |
+
|
634 |
+
# เพิ่มสถิติการเขียน
|
635 |
+
stats_text = (
|
636 |
+
f"Total Points: {st.session_state.points['total']}<br/>"
|
637 |
+
f"Perfect Sentences: {st.session_state.points['perfect_sentences']}<br/>"
|
638 |
+
f"Accuracy Rate: {st.session_state.stats['accuracy_rate']:.1f}%<br/>"
|
639 |
+
f"Unique Words Used: {len(st.session_state.stats['vocabulary_used'])}"
|
640 |
+
)
|
641 |
+
elements.append(Paragraph(stats_text, stats_style))
|
642 |
+
elements.append(Spacer(1, 30))
|
643 |
+
|
644 |
+
# เพิ่มเนื้อเรื่อง
|
645 |
+
elements.append(Paragraph("The Story", styles['Heading2']))
|
646 |
+
for entry in st.session_state.story:
|
647 |
+
if entry['role'] == 'You':
|
648 |
+
text = f"👤 {entry['content']}"
|
649 |
+
if entry.get('is_correct'):
|
650 |
+
style = ParagraphStyle(
|
651 |
+
'Correct',
|
652 |
+
parent=story_style,
|
653 |
+
textColor=colors.darkgreen
|
654 |
+
)
|
655 |
+
else:
|
656 |
+
style = story_style
|
657 |
+
else: # AI response
|
658 |
+
text = f"🤖 {entry['content']}"
|
659 |
+
style = ParagraphStyle(
|
660 |
+
'AI',
|
661 |
+
parent=story_style,
|
662 |
+
textColor=colors.navy
|
663 |
+
)
|
664 |
+
elements.append(Paragraph(text, style))
|
665 |
+
|
666 |
+
# เพิ่ม achievements ที่ได้รับ
|
667 |
+
if st.session_state.achievements:
|
668 |
+
elements.append(Spacer(1, 20))
|
669 |
+
elements.append(Paragraph("Achievements Earned", styles['Heading2']))
|
670 |
+
for achievement in st.session_state.achievements:
|
671 |
+
elements.append(Paragraph(f"🏆 {achievement}", stats_style))
|
672 |
+
|
673 |
+
# สร้าง PDF
|
674 |
+
doc.build(elements)
|
675 |
+
pdf = buffer.getvalue()
|
676 |
+
buffer.close()
|
677 |
+
return pdf
|
678 |
+
|
679 |
+
# เพิ่มฟังก์ชันโหลดความก้าวหน้า
|
680 |
+
def load_progress(uploaded_file):
|
681 |
+
"""โหลดความก้าวหน้าจากไฟล์ JSON"""
|
682 |
+
try:
|
683 |
+
data = json.loads(uploaded_file.getvalue())
|
684 |
+
st.session_state.level = data['level']
|
685 |
+
st.session_state.story = data['story']
|
686 |
+
st.session_state.achievements = data['achievements']
|
687 |
+
st.session_state.points = data['points']
|
688 |
+
st.session_state.stats = data['stats']
|
689 |
+
st.session_state.stats['vocabulary_used'] = set(data['stats']['vocabulary_used'])
|
690 |
+
st.success("โหลดความก้าวหน้าเรียบร้อย!")
|
691 |
+
st.rerun()
|
692 |
+
except Exception as e:
|
693 |
+
st.error(f"เกิดข้อผิดพลาดในการโหลดไฟล์: {str(e)}")
|
694 |
+
|
695 |
def reset_story():
|
696 |
"""Reset the story and related state variables."""
|
697 |
st.session_state.story = []
|
|
|
712 |
|
713 |
# Sidebar for settings
|
714 |
with st.sidebar:
|
715 |
+
st.markdown("### 📂 โห���ดความก้าวหน้า")
|
716 |
+
uploaded_file = st.file_uploader(
|
717 |
+
"เลือกไฟล์ .json",
|
718 |
+
type=['json'],
|
719 |
+
help="เลือกไฟล์ความก้าวหน้าที่บันทึกไว้"
|
720 |
+
)
|
721 |
+
if uploaded_file:
|
722 |
+
if st.button("โหลดความก้าวหน้า"):
|
723 |
+
load_progress(uploaded_file)
|
724 |
+
|
725 |
st.markdown("""
|
726 |
<div class="thai">
|
727 |
🎯 เลือกระดับการเรียนรู้
|
|
|
748 |
if st.button("เริ่มเรื่องใหม่ | Start New Story"):
|
749 |
st.session_state.should_reset = True
|
750 |
st.rerun()
|
751 |
+
|
752 |
|
753 |
# Main content area
|
754 |
col1, col2 = st.columns([3, 1])
|
|
|
897 |
|
898 |
# Save Story Button
|
899 |
if st.session_state.story:
|
900 |
+
st.markdown("### 💾 บันทึกเรื่องราว")
|
901 |
+
col1, col2 = st.columns(2)
|
902 |
+
|
903 |
+
with col1:
|
904 |
+
# บันทึกเป็น PDF
|
905 |
+
pdf = create_story_pdf()
|
906 |
+
st.download_button(
|
907 |
+
label="📑 ดาวน์โหลดเป็น PDF",
|
908 |
+
data=pdf,
|
909 |
+
file_name=f"my_story_{datetime.now().strftime('%Y%m%d')}.pdf",
|
910 |
+
mime="application/pdf"
|
911 |
+
)
|
912 |
+
|
913 |
+
with col2:
|
914 |
+
# บันทึกข้อมูลดิบ (JSON) สำหรับโหลดกลับมาเล่นต่อ
|
915 |
story_data = {
|
916 |
'level': st.session_state.level,
|
917 |
+
'date': datetime.now().isoformat(),
|
918 |
'story': st.session_state.story,
|
919 |
+
'achievements': st.session_state.achievements,
|
920 |
+
'points': st.session_state.points,
|
921 |
+
'stats': {
|
922 |
+
'total_sentences': st.session_state.stats['total_sentences'],
|
923 |
+
'correct_first_try': st.session_state.stats['correct_first_try'],
|
924 |
+
'accuracy_rate': st.session_state.stats['accuracy_rate'],
|
925 |
+
'vocabulary_used': list(st.session_state.stats['vocabulary_used'])
|
926 |
+
}
|
927 |
}
|
928 |
st.download_button(
|
929 |
+
label="💾 บันทึกความก้าวหน้า",
|
930 |
data=json.dumps(story_data, indent=2),
|
931 |
+
file_name=f"story_progress_{datetime.now().strftime('%Y%m%d')}.json",
|
932 |
+
mime="application/json"
|
933 |
)
|