Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -732,16 +732,17 @@ class NovelDatabase:
|
|
732 |
|
733 |
char_latest_states = {}
|
734 |
for row in cursor.fetchall():
|
735 |
-
|
736 |
-
|
|
|
737 |
char_state = CharacterState(
|
738 |
name=char_name,
|
739 |
-
alive=bool(
|
740 |
-
location=
|
741 |
-
injuries=json.loads(
|
742 |
-
emotional_state=
|
743 |
-
relationships=json.loads(
|
744 |
-
last_seen_chapter=
|
745 |
)
|
746 |
char_latest_states[char_name] = char_state
|
747 |
|
@@ -755,12 +756,13 @@ class NovelDatabase:
|
|
755 |
''', (session_id,))
|
756 |
|
757 |
for row in cursor.fetchall():
|
|
|
758 |
plot_point = PlotPoint(
|
759 |
-
chapter=
|
760 |
-
event_type=
|
761 |
-
description=
|
762 |
-
characters_involved=json.loads(
|
763 |
-
impact_level=
|
764 |
)
|
765 |
tracker.plot_points.append(plot_point)
|
766 |
|
@@ -980,6 +982,13 @@ class NovelDatabase:
|
|
980 |
return datetime.fromisoformat(datetime_str)
|
981 |
except:
|
982 |
return datetime.strptime(datetime_str, "%Y-%m-%d %H:%M:%S")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
983 |
|
984 |
|
985 |
class NovelWritingSystem:
|
@@ -2187,9 +2196,10 @@ Five years ago, her younger sister Seojin had died in a car accident. The memory
|
|
2187 |
self.current_session_id = session_id
|
2188 |
session = NovelDatabase.get_session(session_id)
|
2189 |
if session:
|
2190 |
-
|
2191 |
-
|
2192 |
-
|
|
|
2193 |
# Load existing state tracker
|
2194 |
self.state_tracker = NovelDatabase.load_session_state_tracker(session_id)
|
2195 |
logger.info(f"Resuming session {session_id} from stage {resume_from_stage}")
|
@@ -2213,11 +2223,13 @@ Five years ago, her younger sister Seojin had died in a car accident. The memory
|
|
2213 |
if resume_from_stage > 0:
|
2214 |
existing_stages = NovelDatabase.get_stages(self.current_session_id)
|
2215 |
for stage_data in existing_stages:
|
|
|
|
|
2216 |
stages.append({
|
2217 |
-
"name":
|
2218 |
-
"status":
|
2219 |
-
"content":
|
2220 |
-
"quality_score":
|
2221 |
})
|
2222 |
|
2223 |
# Define all stages for 10 writers
|
@@ -2601,11 +2613,12 @@ def get_active_sessions(language: str) -> List[Tuple[str, str]]:
|
|
2601 |
|
2602 |
choices = []
|
2603 |
for session in sessions:
|
2604 |
-
|
|
|
2605 |
date_str = created.strftime("%Y-%m-%d %H:%M")
|
2606 |
-
query_preview =
|
2607 |
-
label = f"[{date_str}] {query_preview} (Stage {
|
2608 |
-
choices.append((label,
|
2609 |
|
2610 |
return choices
|
2611 |
except Exception as e:
|
@@ -2631,11 +2644,12 @@ def auto_recover_session(language: str) -> Tuple[str, str]:
|
|
2631 |
try:
|
2632 |
latest_session = NovelDatabase.get_latest_active_session()
|
2633 |
if latest_session:
|
|
|
2634 |
if language == "Korean":
|
2635 |
-
message = f"โ
์๋ ๋ณต๊ตฌ: '{
|
2636 |
else:
|
2637 |
-
message = f"โ
Auto recovered: '{
|
2638 |
-
return
|
2639 |
else:
|
2640 |
return None, ""
|
2641 |
except Exception as e:
|
@@ -2691,8 +2705,11 @@ def download_novel(novel_text: str, format: str, language: str, session_id: str
|
|
2691 |
logger.error(f"Session not found: {session_id}")
|
2692 |
return None
|
2693 |
|
|
|
|
|
|
|
2694 |
# ์ธ์
์ ์ค์ ์ธ์ด ์ฌ์ฉ
|
2695 |
-
actual_language =
|
2696 |
logger.info(f"Using session language: {actual_language}")
|
2697 |
|
2698 |
# DB์์ ๋ชจ๋ ์คํ
์ด์ง ๊ฐ์ ธ์ค๊ธฐ
|
@@ -2700,13 +2717,13 @@ def download_novel(novel_text: str, format: str, language: str, session_id: str
|
|
2700 |
logger.info(f"Found {len(stages)} stages in database")
|
2701 |
|
2702 |
# ํ์ง ์ ์ ๊ฐ์ ธ์ค๊ธฐ
|
2703 |
-
quality_scores = json.loads(
|
2704 |
|
2705 |
# ํ
์คํธ ๋ชจ๋ ๊ฐ์ง
|
2706 |
is_test_mode = False
|
2707 |
-
has_writer10 = any(stage
|
2708 |
-
has_writer1 = any(stage
|
2709 |
-
has_writer3 = any(stage
|
2710 |
|
2711 |
if has_writer10 and has_writer1 and not has_writer3:
|
2712 |
is_test_mode = True
|
@@ -2734,7 +2751,7 @@ def download_novel(novel_text: str, format: str, language: str, session_id: str
|
|
2734 |
|
2735 |
theme_para = doc.add_paragraph()
|
2736 |
theme_label = '์ฃผ์ : ' if actual_language == 'Korean' else 'Theme: '
|
2737 |
-
theme_run = theme_para.add_run(f'{theme_label}{
|
2738 |
theme_run.font.size = Pt(12)
|
2739 |
theme_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
2740 |
|
@@ -2770,9 +2787,10 @@ def download_novel(novel_text: str, format: str, language: str, session_id: str
|
|
2770 |
if is_test_mode:
|
2771 |
# ํ
์คํธ ๋ชจ๋: writer1 revision + writer10 ๋ด์ฉ ์ฒ๋ฆฌ
|
2772 |
for stage in stages:
|
2773 |
-
|
2774 |
-
|
2775 |
-
|
|
|
2776 |
|
2777 |
# Writer 1 ์์ ๋ณธ
|
2778 |
if role == 'writer1' and stage_name and ('Revision' in stage_name or '์์ ๋ณธ' in stage_name):
|
@@ -2781,13 +2799,13 @@ def download_novel(novel_text: str, format: str, language: str, session_id: str
|
|
2781 |
content = content.strip()
|
2782 |
|
2783 |
if content:
|
2784 |
-
word_count =
|
2785 |
total_words += word_count
|
2786 |
writer_contents.append({
|
2787 |
'writer_num': 1,
|
2788 |
'content': content,
|
2789 |
'word_count': word_count,
|
2790 |
-
'quality_score':
|
2791 |
})
|
2792 |
writer_count = 1
|
2793 |
logger.info(f"Added writer 1 (Chapter 1): {word_count} words")
|
@@ -2811,7 +2829,7 @@ def download_novel(novel_text: str, format: str, language: str, session_id: str
|
|
2811 |
'writer_num': chapter_num,
|
2812 |
'content': chapter_content,
|
2813 |
'word_count': word_count,
|
2814 |
-
'quality_score':
|
2815 |
})
|
2816 |
writer_count = max(writer_count, chapter_num)
|
2817 |
logger.info(f"Added Chapter {chapter_num}: {word_count} words")
|
@@ -2820,9 +2838,10 @@ def download_novel(novel_text: str, format: str, language: str, session_id: str
|
|
2820 |
logger.info("[NORMAL MODE] Processing all writer revisions...")
|
2821 |
|
2822 |
for stage in stages:
|
2823 |
-
|
2824 |
-
|
2825 |
-
|
|
|
2826 |
|
2827 |
# ์๊ฐ ์์ ๋ณธ ์ฐพ๊ธฐ
|
2828 |
is_writer = role and role.startswith('writer')
|
@@ -2841,13 +2860,13 @@ def download_novel(novel_text: str, format: str, language: str, session_id: str
|
|
2841 |
content = content.strip()
|
2842 |
|
2843 |
if content:
|
2844 |
-
word_count =
|
2845 |
total_words += word_count
|
2846 |
writer_contents.append({
|
2847 |
'writer_num': writer_num,
|
2848 |
'content': content,
|
2849 |
'word_count': word_count,
|
2850 |
-
'quality_score':
|
2851 |
})
|
2852 |
writer_count += 1
|
2853 |
logger.info(f"Added writer {writer_num}: {word_count} words")
|
@@ -2967,7 +2986,7 @@ def download_novel(novel_text: str, format: str, language: str, session_id: str
|
|
2967 |
|
2968 |
# Save
|
2969 |
temp_dir = tempfile.gettempdir()
|
2970 |
-
safe_filename = re.sub(r'[^\w\s-]', '',
|
2971 |
mode_suffix = "_TestMode" if is_test_mode else "_Complete"
|
2972 |
filename = f"Novel{mode_suffix}_{safe_filename}_{timestamp}.docx"
|
2973 |
filepath = os.path.join(temp_dir, filename)
|
@@ -2978,7 +2997,7 @@ def download_novel(novel_text: str, format: str, language: str, session_id: str
|
|
2978 |
else:
|
2979 |
# TXT format
|
2980 |
temp_dir = tempfile.gettempdir()
|
2981 |
-
safe_filename = re.sub(r'[^\w\s-]', '',
|
2982 |
mode_suffix = "_TestMode" if is_test_mode else "_Complete"
|
2983 |
filename = f"Novel{mode_suffix}_{safe_filename}_{timestamp}.txt"
|
2984 |
filepath = os.path.join(temp_dir, filename)
|
@@ -2992,14 +3011,14 @@ def download_novel(novel_text: str, format: str, language: str, session_id: str
|
|
2992 |
f.write("="*60 + "\n")
|
2993 |
|
2994 |
if actual_language == 'Korean':
|
2995 |
-
f.write(f"์ฃผ์ : {
|
2996 |
f.write(f"์ธ์ด: ํ๊ตญ์ด\n")
|
2997 |
f.write(f"์์ฑ์ผ: {datetime.now()}\n")
|
2998 |
f.write(f"๋ชจ๋: {'ํ
์คํธ ๋ชจ๋ (์ค์ ์์ฑ๋ ์ฑํฐ)' if is_test_mode else '์ ์ฒด ๋ชจ๋ (10๊ฐ ์ฑํฐ)'}\n")
|
2999 |
if quality_scores:
|
3000 |
f.write(f"ํ์ง ์ ์: {quality_scores.get('overall', 0):.1f}/10\n")
|
3001 |
else:
|
3002 |
-
f.write(f"Theme: {
|
3003 |
f.write(f"Language: English\n")
|
3004 |
f.write(f"Created: {datetime.now()}\n")
|
3005 |
f.write(f"Mode: {'Test Mode (Actual chapters)' if is_test_mode else 'Full Mode (10 chapters)'}\n")
|
@@ -3016,9 +3035,10 @@ def download_novel(novel_text: str, format: str, language: str, session_id: str
|
|
3016 |
if is_test_mode:
|
3017 |
# ํ
์คํธ ๋ชจ๋ ์ฒ๋ฆฌ (DOCX์ ๋์ผ)
|
3018 |
for stage in stages:
|
3019 |
-
|
3020 |
-
|
3021 |
-
|
|
|
3022 |
|
3023 |
if role == 'writer1' and stage_name and ('Revision' in stage_name or '์์ ๋ณธ' in stage_name):
|
3024 |
content = re.sub(r'\[(?:ํ์ด์ง|Page|page)\s*\d+\]', '', content)
|
@@ -3026,7 +3046,7 @@ def download_novel(novel_text: str, format: str, language: str, session_id: str
|
|
3026 |
content = content.strip()
|
3027 |
|
3028 |
if content:
|
3029 |
-
word_count =
|
3030 |
total_words += word_count
|
3031 |
writer_count = 1
|
3032 |
|
@@ -3037,8 +3057,8 @@ def download_novel(novel_text: str, format: str, language: str, session_id: str
|
|
3037 |
f.write(f"{chapter_title}\n")
|
3038 |
word_count_label = f"๋จ์ด ์: {word_count:,}" if actual_language == 'Korean' else f"Word Count: {word_count:,}"
|
3039 |
f.write(f"{word_count_label}\n")
|
3040 |
-
if
|
3041 |
-
quality_label = f"ํ์ง: {
|
3042 |
f.write(f"{quality_label}\n")
|
3043 |
f.write(f"{'='*40}\n\n")
|
3044 |
f.write(content)
|
@@ -3070,9 +3090,10 @@ def download_novel(novel_text: str, format: str, language: str, session_id: str
|
|
3070 |
else:
|
3071 |
# ์ผ๋ฐ ๋ชจ๋
|
3072 |
for stage in stages:
|
3073 |
-
|
3074 |
-
|
3075 |
-
|
|
|
3076 |
|
3077 |
is_writer = role and role.startswith('writer')
|
3078 |
is_revision = stage_name and ('Revision' in stage_name or '์์ ๋ณธ' in stage_name)
|
@@ -3088,7 +3109,7 @@ def download_novel(novel_text: str, format: str, language: str, session_id: str
|
|
3088 |
content = content.strip()
|
3089 |
|
3090 |
if content:
|
3091 |
-
word_count =
|
3092 |
total_words += word_count
|
3093 |
writer_count += 1
|
3094 |
|
@@ -3099,8 +3120,8 @@ def download_novel(novel_text: str, format: str, language: str, session_id: str
|
|
3099 |
f.write(f"{chapter_title}\n")
|
3100 |
word_count_label = f"๋จ์ด ์: {word_count:,}" if actual_language == 'Korean' else f"Word Count: {word_count:,}"
|
3101 |
f.write(f"{word_count_label}\n")
|
3102 |
-
if
|
3103 |
-
quality_label = f"ํ์ง: {
|
3104 |
f.write(f"{quality_label}\n")
|
3105 |
f.write(f"{'='*40}\n\n")
|
3106 |
f.write(content)
|
|
|
732 |
|
733 |
char_latest_states = {}
|
734 |
for row in cursor.fetchall():
|
735 |
+
row_dict = dict(row) # Convert Row to dict
|
736 |
+
char_name = row_dict['character_name']
|
737 |
+
if char_name not in char_latest_states or row_dict['chapter'] > char_latest_states[char_name].last_seen_chapter:
|
738 |
char_state = CharacterState(
|
739 |
name=char_name,
|
740 |
+
alive=bool(row_dict['is_alive']),
|
741 |
+
location=row_dict['location'] or "",
|
742 |
+
injuries=json.loads(row_dict['injuries']) if row_dict['injuries'] else [],
|
743 |
+
emotional_state=row_dict['emotional_state'] or "",
|
744 |
+
relationships=json.loads(row_dict['relationships']) if row_dict['relationships'] else {},
|
745 |
+
last_seen_chapter=row_dict['chapter']
|
746 |
)
|
747 |
char_latest_states[char_name] = char_state
|
748 |
|
|
|
756 |
''', (session_id,))
|
757 |
|
758 |
for row in cursor.fetchall():
|
759 |
+
row_dict = dict(row) # Convert Row to dict
|
760 |
plot_point = PlotPoint(
|
761 |
+
chapter=row_dict['chapter'],
|
762 |
+
event_type=row_dict['event_type'],
|
763 |
+
description=row_dict['description'],
|
764 |
+
characters_involved=json.loads(row_dict['characters_involved']) if row_dict['characters_involved'] else [],
|
765 |
+
impact_level=row_dict['impact_level']
|
766 |
)
|
767 |
tracker.plot_points.append(plot_point)
|
768 |
|
|
|
982 |
return datetime.fromisoformat(datetime_str)
|
983 |
except:
|
984 |
return datetime.strptime(datetime_str, "%Y-%m-%d %H:%M:%S")
|
985 |
+
|
986 |
+
@staticmethod
|
987 |
+
def row_to_dict(row):
|
988 |
+
"""Convert sqlite3.Row to dictionary"""
|
989 |
+
if row is None:
|
990 |
+
return None
|
991 |
+
return dict(row) if hasattr(row, 'keys') else row
|
992 |
|
993 |
|
994 |
class NovelWritingSystem:
|
|
|
2196 |
self.current_session_id = session_id
|
2197 |
session = NovelDatabase.get_session(session_id)
|
2198 |
if session:
|
2199 |
+
session_dict = dict(session) # Convert Row to dict
|
2200 |
+
query = session_dict['user_query']
|
2201 |
+
language = session_dict['language']
|
2202 |
+
resume_from_stage = session_dict['current_stage'] + 1
|
2203 |
# Load existing state tracker
|
2204 |
self.state_tracker = NovelDatabase.load_session_state_tracker(session_id)
|
2205 |
logger.info(f"Resuming session {session_id} from stage {resume_from_stage}")
|
|
|
2223 |
if resume_from_stage > 0:
|
2224 |
existing_stages = NovelDatabase.get_stages(self.current_session_id)
|
2225 |
for stage_data in existing_stages:
|
2226 |
+
# Convert sqlite3.Row to dict
|
2227 |
+
stage_dict = dict(stage_data)
|
2228 |
stages.append({
|
2229 |
+
"name": stage_dict['stage_name'],
|
2230 |
+
"status": stage_dict['status'],
|
2231 |
+
"content": stage_dict['content'] or "",
|
2232 |
+
"quality_score": stage_dict.get('quality_score', 0.0)
|
2233 |
})
|
2234 |
|
2235 |
# Define all stages for 10 writers
|
|
|
2613 |
|
2614 |
choices = []
|
2615 |
for session in sessions:
|
2616 |
+
session_dict = dict(session) # Convert Row to dict
|
2617 |
+
created = NovelDatabase.parse_datetime(session_dict['created_at'])
|
2618 |
date_str = created.strftime("%Y-%m-%d %H:%M")
|
2619 |
+
query_preview = session_dict['user_query'][:50] + "..." if len(session_dict['user_query']) > 50 else session_dict['user_query']
|
2620 |
+
label = f"[{date_str}] {query_preview} (Stage {session_dict['current_stage']})"
|
2621 |
+
choices.append((label, session_dict['session_id']))
|
2622 |
|
2623 |
return choices
|
2624 |
except Exception as e:
|
|
|
2644 |
try:
|
2645 |
latest_session = NovelDatabase.get_latest_active_session()
|
2646 |
if latest_session:
|
2647 |
+
session_dict = dict(latest_session) # Convert Row to dict
|
2648 |
if language == "Korean":
|
2649 |
+
message = f"โ
์๋ ๋ณต๊ตฌ: '{session_dict['user_query'][:30]}...' (Stage {session_dict['current_stage']})"
|
2650 |
else:
|
2651 |
+
message = f"โ
Auto recovered: '{session_dict['user_query'][:30]}...' (Stage {session_dict['current_stage']})"
|
2652 |
+
return session_dict['session_id'], message
|
2653 |
else:
|
2654 |
return None, ""
|
2655 |
except Exception as e:
|
|
|
2705 |
logger.error(f"Session not found: {session_id}")
|
2706 |
return None
|
2707 |
|
2708 |
+
# Convert sqlite3.Row to dict
|
2709 |
+
session_dict = dict(session) if session else {}
|
2710 |
+
|
2711 |
# ์ธ์
์ ์ค์ ์ธ์ด ์ฌ์ฉ
|
2712 |
+
actual_language = session_dict['language']
|
2713 |
logger.info(f"Using session language: {actual_language}")
|
2714 |
|
2715 |
# DB์์ ๋ชจ๋ ์คํ
์ด์ง ๊ฐ์ ธ์ค๊ธฐ
|
|
|
2717 |
logger.info(f"Found {len(stages)} stages in database")
|
2718 |
|
2719 |
# ํ์ง ์ ์ ๊ฐ์ ธ์ค๊ธฐ
|
2720 |
+
quality_scores = json.loads(session_dict.get('quality_scores', '{}')) if session_dict.get('quality_scores') else {}
|
2721 |
|
2722 |
# ํ
์คํธ ๋ชจ๋ ๊ฐ์ง
|
2723 |
is_test_mode = False
|
2724 |
+
has_writer10 = any(dict(stage).get('role') == 'writer10' for stage in stages)
|
2725 |
+
has_writer1 = any(dict(stage).get('role') == 'writer1' for stage in stages)
|
2726 |
+
has_writer3 = any(dict(stage).get('role') == 'writer3' for stage in stages)
|
2727 |
|
2728 |
if has_writer10 and has_writer1 and not has_writer3:
|
2729 |
is_test_mode = True
|
|
|
2751 |
|
2752 |
theme_para = doc.add_paragraph()
|
2753 |
theme_label = '์ฃผ์ : ' if actual_language == 'Korean' else 'Theme: '
|
2754 |
+
theme_run = theme_para.add_run(f'{theme_label}{session_dict["user_query"]}')
|
2755 |
theme_run.font.size = Pt(12)
|
2756 |
theme_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
2757 |
|
|
|
2787 |
if is_test_mode:
|
2788 |
# ํ
์คํธ ๋ชจ๋: writer1 revision + writer10 ๋ด์ฉ ์ฒ๋ฆฌ
|
2789 |
for stage in stages:
|
2790 |
+
stage_dict = dict(stage) # Convert Row to dict
|
2791 |
+
role = stage_dict.get('role')
|
2792 |
+
stage_name = stage_dict.get('stage_name', '')
|
2793 |
+
content = stage_dict.get('content', '')
|
2794 |
|
2795 |
# Writer 1 ์์ ๋ณธ
|
2796 |
if role == 'writer1' and stage_name and ('Revision' in stage_name or '์์ ๋ณธ' in stage_name):
|
|
|
2799 |
content = content.strip()
|
2800 |
|
2801 |
if content:
|
2802 |
+
word_count = stage_dict.get('word_count', len(content.split()))
|
2803 |
total_words += word_count
|
2804 |
writer_contents.append({
|
2805 |
'writer_num': 1,
|
2806 |
'content': content,
|
2807 |
'word_count': word_count,
|
2808 |
+
'quality_score': stage_dict.get('quality_score', 0)
|
2809 |
})
|
2810 |
writer_count = 1
|
2811 |
logger.info(f"Added writer 1 (Chapter 1): {word_count} words")
|
|
|
2829 |
'writer_num': chapter_num,
|
2830 |
'content': chapter_content,
|
2831 |
'word_count': word_count,
|
2832 |
+
'quality_score': stage_dict.get('quality_score', 0)
|
2833 |
})
|
2834 |
writer_count = max(writer_count, chapter_num)
|
2835 |
logger.info(f"Added Chapter {chapter_num}: {word_count} words")
|
|
|
2838 |
logger.info("[NORMAL MODE] Processing all writer revisions...")
|
2839 |
|
2840 |
for stage in stages:
|
2841 |
+
stage_dict = dict(stage) # Convert Row to dict
|
2842 |
+
role = stage_dict.get('role')
|
2843 |
+
stage_name = stage_dict.get('stage_name', '')
|
2844 |
+
content = stage_dict.get('content', '')
|
2845 |
|
2846 |
# ์๊ฐ ์์ ๋ณธ ์ฐพ๊ธฐ
|
2847 |
is_writer = role and role.startswith('writer')
|
|
|
2860 |
content = content.strip()
|
2861 |
|
2862 |
if content:
|
2863 |
+
word_count = stage_dict.get('word_count', len(content.split()))
|
2864 |
total_words += word_count
|
2865 |
writer_contents.append({
|
2866 |
'writer_num': writer_num,
|
2867 |
'content': content,
|
2868 |
'word_count': word_count,
|
2869 |
+
'quality_score': stage_dict.get('quality_score', 0)
|
2870 |
})
|
2871 |
writer_count += 1
|
2872 |
logger.info(f"Added writer {writer_num}: {word_count} words")
|
|
|
2986 |
|
2987 |
# Save
|
2988 |
temp_dir = tempfile.gettempdir()
|
2989 |
+
safe_filename = re.sub(r'[^\w\s-]', '', session_dict['user_query'][:30]).strip()
|
2990 |
mode_suffix = "_TestMode" if is_test_mode else "_Complete"
|
2991 |
filename = f"Novel{mode_suffix}_{safe_filename}_{timestamp}.docx"
|
2992 |
filepath = os.path.join(temp_dir, filename)
|
|
|
2997 |
else:
|
2998 |
# TXT format
|
2999 |
temp_dir = tempfile.gettempdir()
|
3000 |
+
safe_filename = re.sub(r'[^\w\s-]', '', session_dict['user_query'][:30]).strip()
|
3001 |
mode_suffix = "_TestMode" if is_test_mode else "_Complete"
|
3002 |
filename = f"Novel{mode_suffix}_{safe_filename}_{timestamp}.txt"
|
3003 |
filepath = os.path.join(temp_dir, filename)
|
|
|
3011 |
f.write("="*60 + "\n")
|
3012 |
|
3013 |
if actual_language == 'Korean':
|
3014 |
+
f.write(f"์ฃผ์ : {session_dict['user_query']}\n")
|
3015 |
f.write(f"์ธ์ด: ํ๊ตญ์ด\n")
|
3016 |
f.write(f"์์ฑ์ผ: {datetime.now()}\n")
|
3017 |
f.write(f"๋ชจ๋: {'ํ
์คํธ ๋ชจ๋ (์ค์ ์์ฑ๋ ์ฑํฐ)' if is_test_mode else '์ ์ฒด ๋ชจ๋ (10๊ฐ ์ฑํฐ)'}\n")
|
3018 |
if quality_scores:
|
3019 |
f.write(f"ํ์ง ์ ์: {quality_scores.get('overall', 0):.1f}/10\n")
|
3020 |
else:
|
3021 |
+
f.write(f"Theme: {session_dict['user_query']}\n")
|
3022 |
f.write(f"Language: English\n")
|
3023 |
f.write(f"Created: {datetime.now()}\n")
|
3024 |
f.write(f"Mode: {'Test Mode (Actual chapters)' if is_test_mode else 'Full Mode (10 chapters)'}\n")
|
|
|
3035 |
if is_test_mode:
|
3036 |
# ํ
์คํธ ๋ชจ๋ ์ฒ๋ฆฌ (DOCX์ ๋์ผ)
|
3037 |
for stage in stages:
|
3038 |
+
stage_dict = dict(stage) # Convert Row to dict
|
3039 |
+
role = stage_dict.get('role')
|
3040 |
+
stage_name = stage_dict.get('stage_name', '')
|
3041 |
+
content = stage_dict.get('content', '')
|
3042 |
|
3043 |
if role == 'writer1' and stage_name and ('Revision' in stage_name or '์์ ๋ณธ' in stage_name):
|
3044 |
content = re.sub(r'\[(?:ํ์ด์ง|Page|page)\s*\d+\]', '', content)
|
|
|
3046 |
content = content.strip()
|
3047 |
|
3048 |
if content:
|
3049 |
+
word_count = stage_dict.get('word_count', len(content.split()))
|
3050 |
total_words += word_count
|
3051 |
writer_count = 1
|
3052 |
|
|
|
3057 |
f.write(f"{chapter_title}\n")
|
3058 |
word_count_label = f"๋จ์ด ์: {word_count:,}" if actual_language == 'Korean' else f"Word Count: {word_count:,}"
|
3059 |
f.write(f"{word_count_label}\n")
|
3060 |
+
if stage_dict.get('quality_score', 0) > 0:
|
3061 |
+
quality_label = f"ํ์ง: {stage_dict['quality_score']:.1f}/10" if actual_language == 'Korean' else f"Quality: {stage_dict['quality_score']:.1f}/10"
|
3062 |
f.write(f"{quality_label}\n")
|
3063 |
f.write(f"{'='*40}\n\n")
|
3064 |
f.write(content)
|
|
|
3090 |
else:
|
3091 |
# ์ผ๋ฐ ๋ชจ๋
|
3092 |
for stage in stages:
|
3093 |
+
stage_dict = dict(stage) # Convert Row to dict
|
3094 |
+
role = stage_dict.get('role')
|
3095 |
+
stage_name = stage_dict.get('stage_name', '')
|
3096 |
+
content = stage_dict.get('content', '')
|
3097 |
|
3098 |
is_writer = role and role.startswith('writer')
|
3099 |
is_revision = stage_name and ('Revision' in stage_name or '์์ ๋ณธ' in stage_name)
|
|
|
3109 |
content = content.strip()
|
3110 |
|
3111 |
if content:
|
3112 |
+
word_count = stage_dict.get('word_count', len(content.split()))
|
3113 |
total_words += word_count
|
3114 |
writer_count += 1
|
3115 |
|
|
|
3120 |
f.write(f"{chapter_title}\n")
|
3121 |
word_count_label = f"๋จ์ด ์: {word_count:,}" if actual_language == 'Korean' else f"Word Count: {word_count:,}"
|
3122 |
f.write(f"{word_count_label}\n")
|
3123 |
+
if stage_dict.get('quality_score', 0) > 0:
|
3124 |
+
quality_label = f"ํ์ง: {stage_dict['quality_score']:.1f}/10" if actual_language == 'Korean' else f"Quality: {stage_dict['quality_score']:.1f}/10"
|
3125 |
f.write(f"{quality_label}\n")
|
3126 |
f.write(f"{'='*40}\n\n")
|
3127 |
f.write(content)
|