whispersound commited on
Commit
3b01e7e
ยท
verified ยท
1 Parent(s): f169dd1

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +612 -0
app.py ADDED
@@ -0,0 +1,612 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import random
3
+ import os
4
+ import re
5
+ import openai
6
+ import textwrap
7
+ from fpdf import FPDF
8
+ from datetime import datetime
9
+ from zoneinfo import ZoneInfo
10
+ from sklearn.feature_extraction.text import CountVectorizer
11
+ from weasyprint import HTML, CSS
12
+ from urllib.request import urlopen
13
+ import tempfile
14
+ import markdown2
15
+ from bs4 import BeautifulSoup
16
+ from PIL import Image
17
+
18
+
19
+
20
+ # Pretendard OTF ํฐํŠธ ํŒŒ์ผ ๊ฒฝ๋กœ ์„ค์ •
21
+ FONT_REGULAR_PATH = os.path.join("Pretendard-Regular.otf")
22
+ FONT_BOLD_PATH = os.path.join("Pretendard-Bold.otf")
23
+
24
+ # OpenAI API ํด๋ผ์ด์–ธํŠธ ์„ค์ •
25
+ openai.api_key = os.getenv("OPENAI_API_KEY")
26
+
27
+ def call_api(content, system_message, max_tokens, temperature, top_p, previous_messages=None):
28
+ try:
29
+ if previous_messages is None:
30
+ previous_messages = []
31
+
32
+ messages = []
33
+ if system_message:
34
+ messages.append({"role": "system", "content": system_message})
35
+
36
+ messages.extend(previous_messages)
37
+ messages.append({"role": "user", "content": content})
38
+
39
+ response = openai.ChatCompletion.create(
40
+ model="gpt-4o-mini",
41
+ messages=messages,
42
+ max_tokens=max_tokens,
43
+ temperature=temperature,
44
+ top_p=top_p,
45
+ request_timeout=50
46
+ )
47
+
48
+ return response.choices[0].message['content']
49
+ except Exception as e:
50
+ print(f"API ํ˜ธ์ถœ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {str(e)}")
51
+ raise
52
+
53
+ def analyze_info(data):
54
+ return f"์„ ํƒํ•œ ์นดํ…Œ๊ณ ๋ฆฌ: {data['category']}\n์„ ํƒํ•œ ํฌ์ŠคํŒ… ์Šคํƒ€์ผ: {data['style']}\n์ฐธ๊ณ  ๊ธ€1: {data['references1']}\n์ฐธ๊ณ  ๊ธ€2: {data['references2']}\n์ฐธ๊ณ  ๊ธ€3: {data['references3']}"
55
+
56
+ def generate_outline(category, style, references1, references2, references3):
57
+ data = {
58
+ 'category': category,
59
+ 'style': style,
60
+ 'references1': references1,
61
+ 'references2': references2,
62
+ 'references3': references3
63
+ }
64
+ full_content = analyze_info(data)
65
+ content = full_content
66
+ system_prompt = get_outline_prompt(data['category']) + "\n\n" + get_style_prompt(data['style'])
67
+ modified_text = call_api(content, system_prompt, 2000, 0.7, 0.95)
68
+ return modified_text
69
+
70
+ def remove_unwanted_phrases(text):
71
+ unwanted_phrases = [
72
+ '์—ฌ๋Ÿฌ๋ถ„', '์ตœ๊ทผ', '๋งˆ์ง€๋ง‰์œผ๋กœ', '๊ฒฐ๋ก ์ ์œผ๋กœ', '๊ฒฐ๊ตญ',
73
+ '์ข…ํ•ฉ์ ์œผ๋กœ', '๋”ฐ๋ผ์„œ', '๋งˆ๋ฌด๋ฆฌ', '์š”์•ฝ'
74
+ ]
75
+ words = re.findall(r'\S+|\n', text)
76
+ result_words = [word for word in words if not any(phrase in word for phrase in unwanted_phrases)]
77
+ return ' '.join(result_words).replace(' \n ', '\n').replace(' \n', '\n').replace('\n ', '\n')
78
+
79
+ def extract_keywords(text, top_n=5):
80
+ vectorizer = CountVectorizer(stop_words='english', ngram_range=(1,2))
81
+ count_matrix = vectorizer.fit_transform([text])
82
+ terms = vectorizer.get_feature_names_out()
83
+ counts = count_matrix.sum(axis=0).A1
84
+ term_counts = sorted(zip(terms, counts), key=lambda x: x[1], reverse=True)
85
+ return [term for term, count in term_counts[:top_n]]
86
+
87
+ def get_group_instruction(group_index):
88
+ instructions = [
89
+ """
90
+ **์ „์ฒด ์ฝ˜ํ…์ธ ๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ์•„์›ƒ๋ผ์ธ ์„น์…˜์˜ ์ผ๋ถ€์ด๋‹ค.**
91
+ 1. ์ฃผ์–ด์ง„ ์•„์›ƒ๋ผ์ธ 1๊ทธ๋ฃน์˜ ์ฒซ๋ฒˆ์งธ์ค„์€ ๋„์ž…๋ถ€์ด๋‹ค.
92
+ 2. ๋ฐ˜๋“œ์‹œ ๋„์ž…๋ถ€์— ๋Œ€ํ•ด์„œ๋งŒ ๊ฐ„๋žตํ•˜๊ฒŒ ์ž‘์„ฑํ•˜๋ผ.
93
+ 3. ๋„์ž…๋ถ€์—์„œ๋Š” ์ฃผ์ œ๋ฅผ ์†Œ๊ฐœํ•˜๊ณ , ๋…์ž์˜ ๊ด€์‹ฌ์„ ๋Œ์–ด์•ผ ํ•œ๋‹ค(๋ฐ˜๋“œ์‹œ 200์ž ์ด๋‚ด๋กœ ์ž‘์„ฑ)
94
+ 4. ์ฃผ์–ด์ง„ ์•„์›ƒ๋ผ์ธ 1๊ทธ๋ฃน์˜ ๋‘๋ฒˆ์งธ์ค„์€ ๋ณธ๋ฌธ1 ์ด๋‹ค.
95
+ 5. ๋ฐ˜๋“œ์‹œ ๋ณธ๋ฌธ1๋กœ์„œ๋งŒ ์ž‘์„ฑํ•˜๋ผ.
96
+ 6. ๋ฐ˜๋“œ์‹œ ๋‹ค์Œ ์„น์…˜์œผ๋กœ์˜ ์ „ํ™˜์„ ์—ผ๋‘์— ๋‘๊ณ  ์ž‘์„ฑํ•˜๋˜, ํ˜„์žฌ ์„น์…˜์„ ์™„์ „ํžˆ ๋งˆ๋ฌด๋ฆฌํ•˜์ง€ ๋ง ๊ฒƒ.
97
+ 7. ๋ณธ๋ฌธ1 ์ฃผ์ œ์˜ ๋‚ด์šฉ์„ ์ƒ์„ธ ๋‹ด์•„ ์•ฝ 190๋‹จ์–ด๋กœ ์ž‘์„ฑํ•˜๋ผ.
98
+ """,
99
+
100
+ """
101
+ **์ „์ฒด ์ฝ˜ํ…์ธ ๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ์•„์›ƒ๋ผ์ธ ์„น์…˜์˜ ์ผ๋ถ€์ด๋‹ค.**
102
+ 1. ์ฃผ์–ด์ง„ ์•„์›ƒ๋ผ์ธ 2๊ทธ๋ฃน์€ ๋ชจ๋‘ ๋ณธ๋ก (๋ณธ๋ก 2~4)์ด๋‹ค.
103
+ 2. ๋ฐ˜๋“œ์‹œ ๋ณธ๋ก ์˜ ํ˜•ํƒœ๋กœ๋งŒ ๋‚ด์šฉ๊ณผ ์ •๋ณด๋ฅผ ๋งค์šฐ ์ž์„ธํ•˜๊ฒŒ ์ž‘์„ฑํ•˜๋ผ.
104
+ 3. ์ด์ „ ์„น์…˜์—์„œ ์ œ์‹œ๋œ ๋‚ด์šฉ๊ณผ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์—ฐ๊ฒฐ๋˜๊ฒŒ ํ๋ฆ„์„ ์œ ์ง€ํ•˜๋ผ.
105
+ 4. ๋ฐ˜๋“œ์‹œ ๊ฒฐ๋ก ์œผ๋กœ ๋„˜์–ด๊ฐ€์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•˜๋ผ.
106
+ 5. ๋ฐ˜๋“œ์‹œ ๊ฐ ์„น์…˜๋ณ„ ์ฃผ์ œ์— ๋งž๋Š” ๋‚ด์šฉ์œผ๋กœ๋กœ ์•ฝ 280~330๋‹จ์–ด๋กœ ์ž‘์„ฑํ•˜๋ผ.
107
+ """,
108
+
109
+ """
110
+ **์ „์ฒด ์ฝ˜ํ…์ธ ๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ์•„์›ƒ๋ผ์ธ ์„น์…˜์˜ ์ผ๋ถ€์ด๋‹ค.**
111
+ 1. ์ฃผ์–ด์ง„ ์•„์›ƒ๋ผ์ธ 3๊ทธ๋ฃน์˜ ์ฒซ๋ฒˆ์งธ์ค„์€ ๋ณธ๋ก 5(๋งˆ์ง€๋ง‰ ๋ณธ๋ก )์ด๋‹ค.
112
+ 2. ๋ฐ˜๋“œ์‹œ ๋ณธ๋ก ์˜ ํ˜•ํƒœ๋กœ๋งŒ ์ž‘์„ฑํ•˜๋ผ.
113
+ 3. ๋ณธ๋ก ์€ ๋ฐ˜๋“œ์‹œ 190๋‹จ์–ด ์ดํ•˜๋กœ ์ž‘์„ฑํ•˜๋ผ.
114
+ 4. ์ฃผ์–ด์ง„ ์•„์›ƒ๋ผ์ธ 3๊ทธ๋ฃน์˜ ๋‘๋ฒˆ์งธ์ค„์€ ์ „์ฒด ์ฝ˜ํ…์ธ ์˜ ๊ฒฐ๋ก ๋ถ€์ด๋‹ค.
115
+ 5. ๋ฐ˜๋“œ์‹œ ๊ฒฐ๋ก ์˜ ํ˜•ํƒœ๋กœ๋งŒ ์ž‘์„ฑํ•˜๋ผ(์ธ์‚ฌ๋ง ๊ธˆ์ง€)
116
+ 6. ๋ฐ˜๋“œ์‹œ ๊ฒฐ๋ก ์—์„œ๋Š” ์ „์ฒด ๋‚ด์šฉ์„ ์š”์•ฝํ•˜๊ณ  ์ตœ์ข… ๋ฉ”์‹œ์ง€๋ฅผ ์ „๋‹ฌํ•˜๋ผ.
117
+ 7. ๊ฒฐ๋ก ์€ 200์ž ์ด๋‚ด๋กœ ์ž‘์„ฑํ•˜๋ผ.
118
+ """
119
+ ]
120
+
121
+ return instructions[group_index]
122
+
123
+ def generate_blog_post(category, style, references1, references2, references3, outline):
124
+ try:
125
+ data = {
126
+ 'category': category,
127
+ 'style': style,
128
+ 'references1': references1,
129
+ 'references2': references2,
130
+ 'references3': references3,
131
+ 'outline': outline
132
+ }
133
+
134
+ system_prompt = get_blog_post_prompt(data['category'])
135
+ style_prompt = get_style_prompt(data['style'])
136
+
137
+ outline_sections = data['outline'].split('\n')
138
+ grouped_sections = [
139
+ outline_sections[:2], # ๋„์ž…๋ถ€ + ๋ณธ๋ฌธ1
140
+ outline_sections[2:5], # ๋ณธ๋ฌธ2 + ๋ณธ๋ฌธ3 + ๋ณธ๋ฌธ4
141
+ outline_sections[5:] # ๋ณธ๋ฌธ5 + ๊ฒฐ๋ก 
142
+ ]
143
+
144
+ sections = []
145
+ previous_content = ""
146
+ previous_messages = []
147
+
148
+ for i, section_group in enumerate(grouped_sections):
149
+ print(f"์„น์…˜ ๊ทธ๋ฃน {i+1}/{len(grouped_sections)} ์ƒ์„ฑ ์ค‘...")
150
+
151
+ max_tokens = [1000, 5000, 1000][i]
152
+
153
+ group_instruction = get_group_instruction(i)
154
+
155
+ user_prompt = f"""
156
+ ์นดํ…Œ๊ณ ๋ฆฌ: {data['category']}
157
+ ํฌ์ŠคํŒ… ์Šคํƒ€์ผ: {data['style']}
158
+ ์ฐธ๊ณ ๊ธ€1: {data['references1']}
159
+ ์ฐธ๊ณ ๊ธ€2: {data['references2']}
160
+ ์ฐธ๊ณ ๊ธ€3: {data['references3']}
161
+ ํ˜„์žฌ ์„น์…˜ ๊ทธ๋ฃน: {' / '.join(section_group)}
162
+ ์ด์ „ ์„น์…˜์˜ ๋งˆ์ง€๋ง‰ ๋‚ด์šฉ: {previous_content}
163
+ ์œ„์˜ ์ •๋ณด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ '{' / '.join(section_group)}' ์„น์…˜ ๊ทธ๋ฃน์˜ ๋‚ด์šฉ์„ ์ž‘์„ฑํ•˜๋˜, ๋‹ค์Œ ์ง€์นจ์„ ๋ฐ˜๋“œ์‹œ ์ค€์ˆ˜ํ•˜๋ผ:
164
+ 1. {group_instruction}
165
+ 2. ์ „์ฒด ์•„์›ƒ๋ผ์ธ์˜ ํ๋ฆ„์„ ๊ณ ๋ คํ•˜์—ฌ ์ผ๊ด€์„ฑ ์žˆ๊ฒŒ ์ž‘์„ฑ.
166
+ 3. ๋ฐ˜๋“œ์‹œ ์ฐธ๊ณ ๊ธ€์˜ ๋‚ด์šฉ์„ ๋ฐ”ํƒ•์œผ๋กœ ๊ตฌ์„ฑํ•˜๋˜, ํ‘œํ˜„์„ ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌํ•˜์ง€ ๋ง ๊ฒƒ.
167
+ 4. ๊ฐ ์„น์…˜์˜ ์ฃผ์š” ๋‚ด์šฉ์„ ์ถฉ๋ถ„ํžˆ ๋‹ค๋ฃจ๋˜, ์ „์ฒด ๊ธ€์˜ ํ๋ฆ„์„ ํ•ด์น˜์ง€ ์•Š๋„๋ก ์ฃผ์˜.
168
+ 5. ์ด์ „ ์„น์…˜๊ณผ์˜ ์—ฐ๊ฒฐ๋ถ€๋ถ„์„ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ด์–ด์ง€๋„๋ก ์ž‘์„ฑ.
169
+ 6. ๊ฐ ์„น์…˜์˜ ์ œ๋ชฉ์„ ์ž‘์„ฑํ•˜๋ผ.
170
+ """
171
+ try:
172
+ section_content = call_api(
173
+ user_prompt,
174
+ system_prompt + "\n" + style_prompt,
175
+ max_tokens,
176
+ 0.7,
177
+ 0.95,
178
+ previous_messages=previous_messages
179
+ )
180
+ sections.append(section_content)
181
+
182
+ lines = section_content.splitlines()
183
+ previous_content = "\n".join(lines[-2:])
184
+
185
+ previous_messages.append({"role": "user", "content": user_prompt})
186
+ previous_messages.append({"role": "assistant", "content": section_content})
187
+ except Exception as e:
188
+ print(f"์„น์…˜ ๊ทธ๋ฃน {i+1} ์ƒ์„ฑ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {str(e)}")
189
+ sections.append(f"์„น์…˜ ๊ทธ๋ฃน {i+1} ์ƒ์„ฑ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ")
190
+
191
+ full_post = "\n\n".join(sections)
192
+ print(f"GPT๊ฐ€ ์ƒ์„ฑํ•œ ์›๋ณธ ๋ธ”๋กœ๊ทธ ๊ธ€:\n{full_post}")
193
+
194
+ filtered_post = remove_unwanted_phrases(full_post)
195
+ filtered_post = filtered_post.lstrip()
196
+
197
+ # HTML๋กœ ๋ณ€ํ™˜
198
+ html_post = convert_to_html(filtered_post)
199
+
200
+ return html_post
201
+ except Exception as e:
202
+ print(f"๊ธ€ ์ƒ์„ฑ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {str(e)}")
203
+ return ""
204
+
205
+ def convert_to_html(text):
206
+ lines = text.split('\n')
207
+ html_lines = []
208
+ for line in lines:
209
+ line = line.strip()
210
+ if line.startswith('####'):
211
+ html_lines.append(f"<h4>{line[4:].strip()}</h4>")
212
+ elif line.startswith('###'):
213
+ html_lines.append(f"<h3>{line[3:].strip()}</h3>")
214
+ elif line.startswith('##'):
215
+ html_lines.append(f"<h2>{line[2:].strip()}</h2>")
216
+ elif line.startswith('#'):
217
+ html_lines.append(f"<h1>{line[1:].strip()}</h1>")
218
+ elif line.startswith('- '): # ๋ฆฌ์ŠคํŠธ ์•„์ดํ…œ
219
+ html_lines.append(f"<li>{line[2:]}</li>")
220
+ elif line: # ์ผ๋ฐ˜ ํ…์ŠคํŠธ (๋นˆ ์ค„ ์ œ์™ธ)
221
+ # '**'๋กœ ๊ฐ์‹ธ์ง„ ๋ถ€๋ถ„์„ <strong> ํƒœ๊ทธ๋กœ ๋ณ€ํ™˜
222
+ line = re.sub(r'\*\*(.*?)\*\*', r'<strong>\1</strong>', line)
223
+ html_lines.append(f"<p>{line}</p>")
224
+ else: # ๋นˆ ์ค„
225
+ html_lines.append("<br>")
226
+
227
+ html_content = f"""
228
+ <div style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
229
+ {"".join(html_lines)}
230
+ </div>
231
+ """
232
+ return html_content
233
+
234
+ def remove_unwanted_phrases(text):
235
+ unwanted_phrases = [
236
+ '์—ฌ๋Ÿฌ๋ถ„', '์ตœ๊ทผ', '๋งˆ์ง€๋ง‰์œผ๋กœ', '๊ฒฐ๋ก ์ ์œผ๋กœ', '๊ฒฐ๊ตญ',
237
+ '์ข…ํ•ฉ์ ์œผ๋กœ', '๋”ฐ๋ผ์„œ', '๋งˆ๋ฌด๋ฆฌ', '์š”์•ฝ'
238
+ ]
239
+
240
+ # ๋ฌธ๋‹จ๋ณ„๋กœ ๋‚˜๋ˆ„์–ด ์ฒ˜๋ฆฌ
241
+ lines = text.split('\n')
242
+ result_lines = []
243
+
244
+ for line in lines:
245
+ if "๋‹ค์Œ ์„น์…˜์—์„œ๋Š”" in line:
246
+ parts = line.split("๋‹ค์Œ ์„น์…˜์—์„œ๋Š”")
247
+ if parts[0].strip():
248
+ result_lines.append(parts[0].strip())
249
+ else:
250
+ # ๋ถˆํ•„์š”ํ•œ ํ‘œํ˜„ ์ œ๊ฑฐ (๊ตฌ๋‘์  ํฌํ•จ)
251
+ for phrase in unwanted_phrases:
252
+ # ๋ถˆํ•„์š”ํ•œ ํ‘œํ˜„ ์•ž๋’ค์˜ ๊ตฌ๋‘์ ๊ณผ ๊ณต๋ฐฑ๊นŒ์ง€ ํฌํ•จํ•˜์—ฌ ์ œ๊ฑฐ
253
+ pattern = rf'(\b{re.escape(phrase)}\b[\s,.!?]*)|([,.!?]*\b{re.escape(phrase)}\b)'
254
+ line = re.sub(pattern, '', line)
255
+
256
+ # ๋ฌธ์žฅ ๋‚ด ์ž”์—ฌ ๊ณต๋ฐฑ ๋ฐ ๊ตฌ๋‘์  ์ •๋ฆฌ
257
+ line = re.sub(r'\s{2,}', ' ', line) # ์—ฐ์† ๊ณต๋ฐฑ ์ œ๊ฑฐ
258
+ line = line.strip() # ์•ž๋’ค ๊ณต๋ฐฑ ์ œ๊ฑฐ
259
+ result_lines.append(line)
260
+
261
+ return '\n'.join(result_lines)
262
+
263
+ def get_outline_prompt(category):
264
+ if (category == "์ผ๋ฐ˜"):
265
+ return """
266
+ [์ƒํ’ˆ๋ฆฌ๋ทฐ ์†Œ์ฃผ์ œ(Outline) ์ƒ์„ฑ ๊ทœ์น™]
267
+ [๊ธฐ๋ณธ๊ทœ์น™]
268
+ 1. ๋ฐ˜๋“œ์‹œ ํ•œ๊ตญ์–ด(ํ•œ๊ธ€)๋กœ ์ž‘์„ฑํ•˜๋ผ
269
+ 2. ๋„ˆ๋Š” ๊ฐ€์žฅ ์ฃผ๋ชฉ๋ฐ›๋Š” ์ „๋ฌธ ๋ธ”๋กœ๊ฑฐ ๋งˆ์ผ€ํ„ฐ์ด๋‹ค.
270
+ 3. ๋งˆ์ผ€ํ„ฐ๋กœ์„œ ์ •๋ณด์ œ๊ณต๊ณผ ๋งˆ์ผ€ํŒ…์— ์ดˆ์ ์„ ๋งž์ถฐ ์ž‘์„ฑํ•˜๋ผ.
271
+ 5. ๋ฐ˜๋“œ์‹œ ๋งˆํฌ๋‹ค์šด ํ˜•์‹์ด ์•„๋‹Œ ์ˆœ์ˆ˜ํ•œ ํ…์ŠคํŠธ๋กœ ์ถœ๋ ฅํ•˜๋ผ
272
+ [์•„์›ƒ๋ผ์ธ ์ž‘์„ฑ ๊ทœ์น™]
273
+ 1. ๋ธ”๋กœ๊ทธ ๊ธ€์„ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•œ ์†Œ์ฃผ์ œ(์„น์…˜)๋งŒ์„ ์ž‘์„ฑํ•˜๋ผ
274
+ 2. ๋ฐ˜๋“œ์‹œ ์ž…๋ ฅ๋œ ์ฐธ๊ณ ๊ธ€๊ณผ ๋ธ”๋กœ๊ทธ ์ฃผ์ œ, ์ œ๋ชฉ์„ ๋ฐ”ํƒ•์œผ๋กœ ํ•ต์‹ฌ ์ฃผ์ œ๋ฅผ ํŒŒ์•…ํ•˜์—ฌ ์†Œ์ฃผ์ œ(์„น์…˜)๋ฅผ ๊ตฌ์„ฑํ•˜๋ผ
275
+ 3. ์ „์ฒด ๋งฅ๋ฝ์— ๋งž๊ฒŒ ์†Œ์ฃผ์ œ(์„น์…˜)๋ฅผ ์ž‘์„ฑ
276
+ 4. ๋ฐ˜๋“œ์‹œ ์†Œ์ œ๋ชฉ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก 30์ž ์ด๋‚ด๋กœ ์ž‘์„ฑํ•˜๋ผ
277
+ 5. ์ฐธ๊ณ ๊ธ€์„ ๋ถ„์„ํ•˜์—ฌ ๋…์ž๊ฐ€ ์–ป๊ณ ์ž ํ•˜๋Š” ํฅ๋ฏธ๋กœ์šด ์ •๋ณด, ๋„์›€์ด ๋˜๋Š” ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋„๋ก ์†Œ์ฃผ์ œ๋ฅผ ์ž‘์„ฑํ•˜๋ผ.
278
+ 6. ๋ฐ˜๋“œ์‹œ [์†Œ์ฃผ์ œ ๊ตฌ์„ฑ]์— ๋งž๊ฒŒ ์†Œ์ฃผ์ œ๋งŒ ์ถœ๋ ฅํ•˜๋ผ
279
+ [์•„์›ƒ๋ผ์ธ ๊ตฌ์„ฑ]
280
+ 1. ๋ฐ˜๋“œ์‹œ [๋„์ž…๋ถ€]-1๊ฐœ, [๋ณธ๋ก ]-5๊ฐœ, [๊ฒฐ๋ก ]-1๊ฐœ๋กœ ๊ตฌ์„ฑํ•˜์—ฌ ์ถœ๋ ฅํ•˜๋ผ
281
+ 2. ๋ฐ˜๋“œ์‹œ [๋„์ž…๋ถ€]์™€ [๊ฒฐ๋ก ]์˜ ์ œ๋ชฉ์ด ์ค‘๋ณต๋˜์ง€ ์•Š๋„๋ก ์ž‘์„ฑํ•˜๋ผ
282
+ ์ถœ๋ ฅ์˜ˆ์‹œ:
283
+ - ๋„์ž…๋ถ€: ์ œ๋ชฉ
284
+ - ๋ณธ๋ก 1: ์ œ๋ชฉ
285
+ ...
286
+ - ๋ณธ๋ก 5: ์ œ๋ชฉ
287
+ - ๊ฒฐ๋ก : ์ œ๋ชฉ
288
+ """
289
+
290
+ elif (category == "์ƒํ™œ๊ฑด๊ฐ•"):
291
+ return """
292
+ [์ƒํ’ˆ๋ฆฌ๋ทฐ ์†Œ์ฃผ์ œ(Outline) ์ƒ์„ฑ ๊ทœ์น™]
293
+ [๊ธฐ๋ณธ๊ทœ์น™]
294
+ 1. ๋ฐ˜๋“œ์‹œ ํ•œ๊ตญ์–ด(ํ•œ๊ธ€)๋กœ ์ž‘์„ฑํ•˜๋ผ
295
+ 2. ๋„ˆ๋Š” ๊ฐ€์žฅ ์ฃผ๋ชฉ๋ฐ›๋Š” '์ƒํ™œ๊ฑด๊ฐ•' ์ „๋ฌธ ๋ธ”๋กœ๊ฑฐ ๋งˆ์ผ€ํ„ฐ์ด๋‹ค.
296
+ 3. ๋ฐ˜๋“œ์‹œ ์ƒํ™œ๊ฑด๊ฐ• ์ธก๋ฉด์—์„œ ์‹ค์šฉ์ ์ธ ์ •๋ณด ์ œ๊ณต์— ์ดˆ์ ์„ ๋งž์ถฐ ์ž‘์„ฑํ•˜๋ผ.
297
+ 4. ๋ฐ˜๋“œ์‹œ ๋งˆํฌ๋‹ค์šด ํ˜•์‹์ด ์•„๋‹Œ ์ˆœ์ˆ˜ํ•œ ํ…์ŠคํŠธ๋กœ ์ถœ๋ ฅํ•˜๋ผ
298
+ [์•„์›ƒ๋ผ์ธ ์ž‘์„ฑ ๊ทœ์น™]
299
+ 1. ๋ธ”๋กœ๊ทธ ๊ธ€์„ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•œ ์†Œ์ฃผ์ œ(์„น์…˜)๋งŒ์„ ์ž‘์„ฑํ•˜๋ผ
300
+ 2. ๋ฐ˜๋“œ์‹œ ์ž…๋ ฅ๋œ ์ฐธ๊ณ ๊ธ€๊ณผ ๋ธ”๋กœ๊ทธ ์ฃผ์ œ, ์ œ๋ชฉ์„ ๋ฐ”ํƒ•์œผ๋กœ ํ•ต์‹ฌ ์ฃผ์ œ๋ฅผ ํŒŒ์•…ํ•˜์—ฌ ์†Œ์ฃผ์ œ(์„น์…˜)๋ฅผ ๊ตฌ์„ฑํ•˜๋ผ
301
+ 3. ์ „์ฒด ๋งฅ๋ฝ์— ๋งž๊ฒŒ ์†Œ์ฃผ์ œ(์„น์…˜)๋ฅผ ์ž‘์„ฑ
302
+ 4. ๋ฐ˜๋“œ์‹œ ์†Œ์ œ๋ชฉ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก 30์ž ์ด๋‚ด๋กœ ์ž‘์„ฑํ•˜๋ผ
303
+ 5. ์ฐธ๊ณ ๊ธ€์„ ๋ถ„์„ํ•˜์—ฌ ๋…์ž๊ฐ€ ์–ป๊ณ ์ž ํ•˜๋Š” ์ƒํ’ˆ์˜ ๊ธฐ๋Šฅ ์ค‘์—์„œ ํฅ๋ฏธ๋กญ๊ณ  ์‹ค์šฉ์ ์ธ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋„๋ก ์†Œ์ฃผ์ œ๋ฅผ ์ž‘์„ฑํ•˜๋ผ.
304
+ 6. ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์—ฐ๊ตฌ ๊ฒฐ๊ณผ๋‚˜ ํ†ต๊ณ„๋“ฑ์„ ์ ์ ˆํžˆ ํ™œ์šฉํ•˜๋ผ
305
+ 7. ๊ฐœ์ธ์˜ ๊ฒฝํ—˜์ด๋‚˜ ์‚ฌ๋ก€๋ฅผ ์ ์ ˆํžˆ ํ™œ์šฉํ•˜๋ผ
306
+ 8. ๋ฌธ์ œ์— ๋Œ€ํ•œ ์›์ธ, ์ฆ์ƒ, ์˜ˆ๋ฐฉ ๋˜๋Š” ์น˜๋ฃŒ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์‹ค์šฉ์ ์ธ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜๋ผ
307
+ 9. ์ „๋ฌธ์ ์ธ ์šฉ์–ด๋Š” ์ ์ ˆํ•œ ์„ค๋ช…๊ณผ ์‰ฌ์šด ์–ดํœ˜๋กœ ๋ณด์ถฉํ•˜๋ผ
308
+ 10. ๋ฐ˜๋“œ์‹œ [์†Œ์ฃผ์ œ ๊ตฌ์„ฑ]์— ๋งž๊ฒŒ ์†Œ์ฃผ์ œ๋งŒ ์ถœ๋ ฅํ•˜๋ผ
309
+ [์•„์›ƒ๋ผ์ธ ๊ตฌ์„ฑ]
310
+ 1. ๋ฐ˜๋“œ์‹œ [๋„์ž…๋ถ€]-1๊ฐœ, [๋ณธ๋ก ]-5๊ฐœ, [๊ฒฐ๋ก ]-1๊ฐœ๋กœ ๊ตฌ์„ฑํ•˜์—ฌ ์ถœ๋ ฅํ•˜๋ผ
311
+ 2. ๋ฐ˜๋“œ์‹œ [๋„์ž…๋ถ€]์™€ [๊ฒฐ๋ก ]์˜ ์ œ๋ชฉ์ด ์ค‘๋ณต๋˜์ง€ ์•Š๋„๋ก ์ž‘์„ฑํ•˜๋ผ
312
+ ์ถœ๋ ฅ์˜ˆ์‹œ:
313
+ - ๋„์ž…๋ถ€: ์ œ๋ชฉ
314
+ - ๋ณธ๋ก 1: ์ œ๋ชฉ
315
+ ...
316
+ - ๋ณธ๋ก 5: ์ œ๋ชฉ
317
+ - ๊ฒฐ๋ก : ์ œ๋ชฉ
318
+ """
319
+
320
+ def get_blog_post_prompt(category):
321
+ if (category == "์ผ๋ฐ˜"):
322
+ return """
323
+ [์ƒํ’ˆ๋ฆฌ๋ทฐ ์ฝ˜ํ…์ธ  ์ƒ์„ฑ ๊ทœ์น™]
324
+ [๊ธฐ๋ณธ๊ทœ์น™]
325
+ 1. ๋ฐ˜๋“œ์‹œ ํ•œ๊ตญ์–ด(ํ•œ๊ธ€)๋กœ ์ž‘์„ฑํ•˜๋ผ
326
+ 2. ๋„ˆ๋Š” ์ „๋ฌธ์ ์ธ ์ฝ˜ํ…์ธ  ์ž‘๊ฐ€์ด๋‹ค. ์ฃผ์–ด์ง„ ์ฃผ์ œ์— ๋Œ€ํ•ด ํ’๋ถ€ํ•˜๊ณ  ๋งค๋ ฅ์ ์ธ ๋‚ด์šฉ์„ ์ž‘์„ฑํ•˜๋ผ
327
+ 3. ๊ฐ ์„น์…˜์„ ๋…๋ฆฝ์ ์ธ ์ •๋ณด ๋‹จ์œ„๋กœ ์ทจ๊ธ‰ํ•˜๋ผ
328
+ 4. ๋‹ค๋ฅธ ์„น์…˜๊ณผ์˜ ์—ฐ๊ฒฐ์„ฑ์„ ๊ณ ๋ คํ•˜๋˜, ๊ฐ ์„น์…˜์ด ๋…๋ฆฝ์ ์œผ๋กœ๋„ ์ดํ•ด๋  ์ˆ˜ ์žˆ๊ฒŒ ์ž‘์„ฑํ•˜๋ผ
329
+ 5. ์ด ์„น์…˜์€ ๋” ํฐ ์ฝ˜ํ…์ธ ์˜ ์ผ๋ถ€์ž„์„ ๋ช…์‹ฌํ•˜๋ผ, ์ „์ฒด์ ์ธ ํ๋ฆ„์„ ํ•ด์น˜์ง€ ์•Š์œผ๋ฉด์„œ ์ฃผ์–ด์ง„ ์ฃผ์ œ๋ฅผ ์ฒ ์ €ํžˆ ์ž‘์„ฑํ•˜๋ผ
330
+ [ํ…์ŠคํŠธ ์ž‘์„ฑ ๊ทœ์น™]
331
+ 1. ๋ฐ˜๋“œ์‹œ ์ž…๋ ฅ๋œ ์†Œ์ฃผ์ œ(์•„์›ƒ๋ผ์ธ)์— ๋งž๊ฒŒ ๊ธ€์„ ์ž‘์„ฑํ•˜๋ผ
332
+ 2. ๋ฐ˜๋“œ์‹œ ์ž…๋ ฅ๋œ ์ฐธ๊ณ ๊ธ€์˜ ๋‚ด์šฉ์œผ๋กœ๋งŒ ๊ตฌ์„ฑ
333
+ 3. ์ „์ฒด ๋งฅ๋ฝ์„ ์ดํ•ดํ•˜๊ณ  ๋ฌธ์žฅ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๋ผ
334
+ 4. ์ œ๊ณต๋œ ์ฐธ๊ณ ๊ธ€์˜ ์–ดํˆฌ๋ฅผ ๋ฐ˜์˜ํ•˜๋˜, ์ ˆ๋Œ€๋กœ ํ•œ ๋ฌธ์žฅ ์ด์ƒ ๊ทธ๋Œ€๋กœ ์ถœ๋ ฅํ•˜์ง€ ๋ง ๊ฒƒ
335
+ 5. ์‰ฝ๊ฒŒ ์ฝ์„ ์ˆ˜ ์žˆ๋„๋ก ์‰ฌ์šด ์–ดํœ˜๋กœ ์ž‘์„ฑ
336
+ 6. ์ฐธ๊ณ ๊ธ€์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ธ€์˜ ์ฃผ์ œ์™€ ์œ ์šฉํ•œ ์ •๋ณด๋ฅผ ํŒŒ์•…ํ•˜์—ฌ ์ž‘์„ฑ
337
+ 7. ๋…์ž์—๊ฒŒ ๋„์›€์ด๋˜๊ณ  ์ด๋“์ด ๋˜๋Š” ์ •๋ณด๋ฅผ ์ž‘์„ฑ
338
+ 8. ๋…์ž์˜ ๊ณต๊ฐ์„ ์–ป๊ณ  ๊ถ๊ธˆ์ฆ์„ ํ•ด๊ฒฐํ•˜๋„๋ก ์ž‘์„ฑ
339
+ """
340
+ elif (category == "์ƒํ™œ๊ฑด๊ฐ•"):
341
+ return """
342
+ [์ƒํ’ˆ๋ฆฌ๋ทฐ ์ฝ˜ํ…์ธ  ์ƒ์„ฑ ๊ทœ์น™]
343
+ [๊ธฐ๋ณธ๊ทœ์น™]
344
+ 1. ๋ฐ˜๋“œ์‹œ ํ•œ๊ตญ์–ด(ํ•œ๏ฟฝ๏ฟฝ)๋กœ ์ž‘์„ฑํ•˜๋ผ
345
+ 2. ๋„ˆ๋Š” ์ „๋ฌธ์ ์ธ ์ƒํ™œ๊ฑด๊ฐ• ์ฝ˜ํ…์ธ  ์ž‘๊ฐ€์ด๋‹ค. ์ฃผ์–ด์ง„ ์ฃผ์ œ์— ๋Œ€ํ•ด ํ’๋ถ€ํ•˜๊ณ  ๋งค๋ ฅ์ ์ธ ๋‚ด์šฉ์„ ์ž‘์„ฑํ•˜๋ผ
346
+ 3. ๊ฐ ์„น์…˜์„ ๋…๋ฆฝ์ ์ธ ์ •๋ณด ๋‹จ์œ„๋กœ ์ทจ๊ธ‰ํ•˜๋ผ
347
+ 4. ๋‹ค๋ฅธ ์„น์…˜๊ณผ์˜ ์—ฐ๊ฒฐ์„ฑ์„ ๊ณ ๋ คํ•˜๋˜, ๊ฐ ์„น์…˜์ด ๋…๋ฆฝ์ ์œผ๋กœ๋„ ์ดํ•ด๋  ์ˆ˜ ์žˆ๊ฒŒ ์ž‘์„ฑํ•˜๋ผ
348
+ 5. ์ด ์„น์…˜์€ ๋” ํฐ ์ฝ˜ํ…์ธ ์˜ ์ผ๋ถ€์ž„์„ ๋ช…์‹ฌํ•˜๋ผ, ์ „์ฒด์ ์ธ ํ๋ฆ„์„ ํ•ด์น˜์ง€ ์•Š์œผ๋ฉด์„œ ์ฃผ์–ด์ง„ ์ฃผ์ œ๋ฅผ ์ฒ ์ €ํžˆ ์ž‘์„ฑํ•˜๋ผ๋ผ
349
+ 6. ๋ฐ˜๋“œ์‹œ ์ƒํ™œ๊ฑด๊ฐ• ๊ด€๋ จ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋„๋ก ์ž‘์„ฑ
350
+ [ํ…์ŠคํŠธ ์ž‘์„ฑ ๊ทœ์น™]
351
+ 1. ๋ฐ˜๋“œ์‹œ ์ž…๋ ฅ๋œ ์†Œ์ฃผ์ œ(์•„์›ƒ๋ผ์ธ)์— ๋งž๊ฒŒ ๊ธ€์„ ์ž‘์„ฑํ•˜๋ผ
352
+ 2. ๋ฐ˜๋“œ์‹œ ์ž…๋ ฅ๋œ ์ฐธ๊ณ ๊ธ€์˜ ๋‚ด์šฉ์œผ๋กœ๋งŒ ๊ตฌ์„ฑ
353
+ 3. ์ „์ฒด ๋งฅ๋ฝ์„ ์ดํ•ดํ•˜๊ณ  ๋ฌธ์žฅ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๋ผ
354
+ 4. ์ œ๊ณต๋œ ์ฐธ๊ณ ๊ธ€์˜ ์–ดํˆฌ๋ฅผ ๋ฐ˜์˜ํ•˜๋˜, ์ ˆ๋Œ€๋กœ ํ•œ ๋ฌธ์žฅ ์ด์ƒ ๊ทธ๋Œ€๋กœ ์ถœ๋ ฅํ•˜์ง€ ๋ง ๊ฒƒ
355
+ 5. ์‰ฝ๊ฒŒ ์ฝ์„ ์ˆ˜ ์žˆ๋„๋ก ์‰ฌ์šด ์–ดํœ˜๋กœ ์ž‘์„ฑ
356
+ 6. ๊ฐœ์ธ์˜ ๊ฒฝํ—˜์ด๋‚˜ ์‚ฌ๋ก€๋ฅผ ์ ์ ˆํžˆ ํ™œ์šฉํ•˜๋ผ
357
+ 7. ๋ฌธ์ œ์— ๋Œ€ํ•œ ์›์ธ, ์ฆ์ƒ, ์˜ˆ๋ฐฉ ๋˜๋Š” ์น˜๋ฃŒ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์‹ค์šฉ์ ์ธ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜๋ผ
358
+ 8. ์ „๋ฌธ์ ์ธ ์šฉ์–ด๋Š” ์ ์ ˆํ•œ ์„ค๋ช…๊ณผ ์‰ฌ์šด ์–ดํœ˜๋กœ ๋ณด์ถฉํ•˜๋ผ(ํ•„์š”์‹œ ์ถœ์ฒ˜๋ฅผ ํ‘œ๊ธฐํ•˜๋ผ)
359
+ """
360
+
361
+ def get_style_prompt(style):
362
+ prompts = {
363
+ "์นœ๊ทผํ•œ": """
364
+ [์นœ๊ทผํ•œ ํฌ์ŠคํŒ… ์Šคํƒ€์ผ ๊ฐ€์ด๋“œ]
365
+ 1. ํ†ค๊ณผ ์–ด์กฐ
366
+ - ๋Œ€ํ™”ํ•˜๋“ฏ ํŽธ์•ˆํ•˜๊ณ  ์นœ๊ทผํ•œ ๋งํˆฌ ์‚ฌ์šฉ
367
+ 2. ๋ฌธ์žฅ ๋ฐ ์–ดํˆฌ
368
+ - ๋ฐ˜๋“œ์‹œ 'ํ•ด์š”์ฒด'๋กœ ์ž‘์„ฑ, ์ ˆ๋Œ€ '์Šต๋‹ˆ๋‹ค'์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋ง ๊ฒƒ.
369
+ - '~์š”'๋กœ ๋๋‚˜๋„๋ก ์ž‘์„ฑ, '~๋‹ค'๋กœ ๋๋‚˜์ง€ ์•Š๊ฒŒ ํ•˜๋ผ
370
+ - ๊ตฌ์–ด์ฒด ํ‘œํ˜„ ์‚ฌ์šฉ (์˜ˆ: "~ํ–ˆ์–ด์š”", "~์ธ ๊ฒƒ ๊ฐ™์•„์š”")
371
+ 3. ์šฉ์–ด ๋ฐ ์„ค๋ช… ๋ฐฉ์‹
372
+ - ์ „๋ฌธ ์šฉ์–ด ๋Œ€์‹  ์‰ฌ์šด ๋‹จ์–ด๋กœ ํ’€์–ด์„œ ์„ค๋ช…
373
+ - ๋น„์œ ๋‚˜ ์€์œ ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ณต์žกํ•œ ๊ฐœ๋… ์„ค๋ช…
374
+ - ์ˆ˜์‚ฌ์˜๋ฌธ๋ฌธ ํ™œ์šฉํ•˜์—ฌ ๋…์ž์™€ ์†Œํ†ตํ•˜๋Š” ๋Š๋‚Œ ์ฃผ๊ธฐ
375
+ ์ฃผ์˜์‚ฌํ•ญ: ๋„ˆ๋ฌด ๊ฐ€๋ฒผ์šด ํ†ค์€ ์ง€์–‘ํ•˜๊ณ , ์ฃผ์ œ์˜ ์ค‘์š”์„ฑ์„ ํ•ด์น˜์ง€ ์•Š๋Š” ์„ ์—์„œ ์นœ๊ทผํ•จ ์œ ์ง€
376
+ (์˜ˆ์‹œ: ์ž‡๋‹˜๋“ค~ ์˜ค๋ ˆ์˜ค ์ฝ”์นด์ฝœ๋ผ๋ง›์ด์ƒˆ๋กœ ์ถœ์‹œ๊ฐ€ ๋๋‹ค๋Š”๊ฑฐ ์•Œ๊ณ  ๊ณ„์…จ๋‚˜์š”?!ใ…Ž ์˜ค๋ ˆ์˜ค ์ฝ”์นด์ฝœ๋ผ๋ง›์€ ์–ด๋–ค์ง€ ์†”์งํ‰๊ณผ๊ตฌ๋งค์ •๋ณด, ๊ฐ€๊ฒฉ, ์นผ๋กœ๋ฆฌ ๋“ฑ์— ๋Œ€ํ•ด ์ž์„ธ~ ํžˆ ์ ์–ด๋ณด๋„๋ก ํ• ๊ป˜์š”! ์˜ค๋ ˆ์˜ค๋ฅผ ์ข‹์•„ํ•˜๋Š” ์•„๋“ค์—๊ฒŒ๊ฐ„์‹์œผ๋กœ ์˜ค๋ ˆ์˜ค ์ฝ”์นด์ฝœ๋ผ๋ง›์„ ์คฌ๋”๋‹ˆ๋ง›์žˆ๋‹ค๊ณ  ์ข‹์•„ํ•˜๋”๋ผ๊ตฌ์š”. ์ฝœ๋ผํ–ฅ์ด ๋‚˜์„œ ๋” ๋งˆ์Œ์— ๋“ ๋‹ค๋ฉฐใ…Ž๊ฐœ์ธ์ ์œผ๋กœ๋Š” ๋ณ„ โญ๏ธโญ๏ธโญ๏ธ.์š”๊ฑด ๊ฐœ์ธ์ฐจ๊ฐ€ ์žˆ์„๊ฑฐ ๊ฐ™์•„์š”~)
377
+ """,
378
+ "์ผ๋ฐ˜": """
379
+ #์ผ๋ฐ˜์ ์ธ ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŒ… ์Šคํƒ€์ผ ๊ฐ€์ด๋“œ
380
+ 1. ํ†ค๊ณผ ์–ด์กฐ
381
+ - ์ค‘๋ฆฝ์ ์ด๊ณ  ๊ฐ๊ด€์ ์ธ ํ†ค ์œ ์ง€
382
+ - ์ ์ ˆํ•œ ์กด๋Œ“๋ง ์‚ฌ์šฉ (์˜ˆ: "~ํ•ฉ๋‹ˆ๋‹ค", "~์ž…๋‹ˆ๋‹ค")
383
+ 2. ๋‚ด์šฉ ๊ตฌ์กฐ ๋ฐ ์ „๊ฐœ
384
+ - ๋ช…ํ™•ํ•œ ์ฃผ์ œ ์ œ์‹œ๋กœ ์‹œ์ž‘
385
+ - ๋…ผ๋ฆฌ์ ์ธ ์ˆœ์„œ๋กœ ์ •๋ณด ์ „๊ฐœ
386
+ - ์ฃผ์š” ํฌ์ธํŠธ๋ฅผ ๊ฐ•์กฐํ•˜๋Š” ์†Œ์ œ๋ชฉ ํ™œ์šฉ
387
+ - ์ ์ ˆํ•œ ๊ธธ์ด์˜ ๋‹จ๋ฝ์œผ๋กœ ๊ตฌ์„ฑ
388
+ 3. ์šฉ์–ด ๋ฐ ์„ค๋ช… ๋ฐฉ์‹
389
+ - ์ผ๋ฐ˜์ ์œผ๋กœ ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šด ์šฉ์–ด ์„ ํƒ
390
+ - ํ•„์š”์‹œ ๊ฐ„๋‹จํ•œ ์„ค๋ช… ์ถ”๊ฐ€
391
+ - ๊ฐ๊ด€์ ์ธ ์ •๋ณด ์ œ๊ณต์— ์ค‘์ 
392
+ 4. ํ…์ŠคํŠธ ๊ตฌ์กฐํ™”
393
+ - ๋ถˆ๋ฆฟ ํฌ์ธํŠธ๋‚˜ ๋ฒˆํ˜ธ ๋งค๊ธฐ๊ธฐ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์ •๋ณด ๊ตฌ์กฐํ™”
394
+ - ์ค‘์š”ํ•œ ์ •๋ณด๋Š” ๊ตต์€ ๊ธ€์”จ๋‚˜ ๊ธฐ์šธ์ž„๊ผด๋กœ ๊ฐ•์กฐ
395
+ 5. ๋…์ž ์ƒํ˜ธ์ž‘์šฉ
396
+ - ์ ์ ˆํžˆ ๋…์ž์˜ ์ƒ๊ฐ์„ ๋ฌป๋Š” ์งˆ๋ฌธ ํฌํ•จ
397
+ - ์ถ”๊ฐ€ ์ •๋ณด๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๋Š” ํ‚ค์›Œ๋“œ ์ œ์‹œ
398
+ 6. ๋งˆ๋ฌด๋ฆฌ
399
+ - ์ฃผ์š” ๋‚ด์šฉ ๊ฐ„๋‹จํžˆ ์š”์•ฝ
400
+ - ์ถ”๊ฐ€ ์ •๋ณด์— ๋Œ€ํ•œ ์•ˆ๋‚ด ์ œ๊ณต
401
+ ์ฃผ์˜์‚ฌํ•ญ: ๋„ˆ๋ฌด ๋”ฑ๋”ฑํ•˜๊ฑฐ๋‚˜ ์ง€๋ฃจํ•˜์ง€ ์•Š๋„๋ก ๊ท ํ˜• ์œ ์ง€
402
+ ์˜ˆ์‹œ: "์ตœ๊ทผ ํ™˜๊ฒฝ ๋ฌธ์ œ๊ฐ€ ๋Œ€๋‘๋˜๋ฉด์„œ '์ œ๋กœ ์›จ์ด์ŠคํŠธ' ๋ผ์ดํ”„์Šคํƒ€์ผ์— ๋Œ€ํ•œ ๊ด€์‹ฌ์ด ๋†’์•„์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ œ๋กœ ์›จ์ด์ŠคํŠธ๋ž€ ์ผ์ƒ์ƒํ™œ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์“ฐ๋ ˆ๊ธฐ๋ฅผ ์ตœ์†Œํ™”ํ•˜๋Š” ์ƒํ™œ ๋ฐฉ์‹์„ ๋งํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” ์ œ๋กœ ์›จ์ด์ŠคํŠธ์˜ ๊ฐœ๋…, ์‹ค์ฒœ ๋ฐฉ๋ฒ•, ๊ทธ๋ฆฌ๊ณ  ๊ทธ ํšจ๊ณผ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋จผ์ € ์ œ๋กœ ์›จ์ด์ŠคํŠธ์˜ ์ •์˜๋ถ€ํ„ฐ ์‚ดํŽด๋ณด๋ฉด...
403
+ """,
404
+ "์ „๋ฌธ์ ์ธ": """
405
+ #์ „๋ฌธ์ ์ธ ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŒ… ์Šคํƒ€์ผ ๊ฐ€์ด๋“œ
406
+ 1. ํ†ค๊ณผ ๊ตฌ์กฐ
407
+ - ๊ณต์‹์ ์ด๊ณ  ํ•™์ˆ ์ ์ธ ํ†ค ์‚ฌ์šฉ
408
+ - ๊ฐ๊ด€์ ์ด๊ณ  ๋ถ„์„์ ์ธ ์ ‘๊ทผ ์œ ์ง€
409
+ - ๋ช…ํ™•ํ•œ ์„œ๋ก , ๋ณธ๋ก , ๊ฒฐ๋ก  ๊ตฌ์กฐ
410
+ - ์ฒด๊ณ„์ ์ธ ๋…ผ์  ์ „๊ฐœ
411
+ - ์„ธ๋ถ€ ์„น์…˜์„ ์œ„ํ•œ ๋ช…ํ™•ํ•œ ์†Œ์ œ๋ชฉ ์‚ฌ์šฉ
412
+ 2. ๋‚ด์šฉ ๊ตฌ์„ฑ ๋ฐ ์ „๊ฐœ
413
+ - ๋ณต์žกํ•œ ๊ฐœ๋…์„ ์ •ํ™•ํžˆ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์žฅ ๊ตฌ์กฐ ์‚ฌ์šฉ
414
+ - ๋…ผ๋ฆฌ์  ์—ฐ๊ฒฐ์„ ์œ„ํ•œ ์ „ํ™˜์–ด ํ™œ์šฉ
415
+ - ํ•ด๋‹น ๋ถ„์•ผ์˜ ์ „๋ฌธ ์šฉ์–ด ์ ๊ทน ํ™œ์šฉ (ํ•„์š”์‹œ ๊ฐ„๋žตํ•œ ์„ค๋ช… ์ œ๊ณต)
416
+ - ์‹ฌ์ธต์ ์ธ ๋ถ„์„๊ณผ ๋น„ํŒ์  ์‚ฌ๊ณ  ์ „๊ฐœ
417
+ - ๋‹ค์–‘ํ•œ ๊ด€์  ์ œ์‹œ ๋ฐ ๋น„๊ต
418
+ 3. ๋ฐ์ดํ„ฐ ๋ฐ ๊ทผ๊ฑฐ ํ™œ์šฉ
419
+ - ํ†ต๊ณ„, ์—ฐ๊ตฌ ๊ฒฐ๊ณผ, ์ „๋ฌธ๊ฐ€ ์˜๊ฒฌ ๋“ฑ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ์ถœ์ฒ˜ ์ธ์šฉ
420
+ - ํ•„์š”์‹œ ๊ฐ์ฃผ๋‚˜ ์ฐธ๊ณ ๋ฌธํ—Œ ๋ชฉ๋ก ํฌํ•จ
421
+ - ์ˆ˜์น˜ ๋ฐ์ดํ„ฐ๋Š” ํ…์ŠคํŠธ๋กœ ๋ช…ํ™•ํžˆ ์„ค๋ช…
422
+ 4. ํ…์ŠคํŠธ ๊ตฌ์กฐํ™”
423
+ - ๋…ผ๋ฆฌ์  ๊ตฌ์กฐ๋ฅผ ๊ฐ•์กฐํ•˜๊ธฐ ์œ„ํ•ด ๋ฒˆํ˜ธ ๋งค๊ธฐ๊ธฐ ์‚ฌ์šฉ
424
+ - ํ•ต์‹ฌ ๊ฐœ๋…์ด๋‚˜ ์šฉ์–ด๋Š” ๊ธฐ์šธ์ž„๊ผด๋กœ ๊ฐ•์กฐ
425
+ - ๊ธด ์ธ์šฉ๋ฌธ์€ ๏ฟฝ๏ฟฝ๏ฟฝ์—ฌ์“ฐ๊ธฐ๋กœ ๊ตฌ๋ถ„
426
+ 5. ๋งˆ๋ฌด๋ฆฌ
427
+ - ํ•ต์‹ฌ ๋…ผ์  ์žฌ๊ฐ•์กฐ
428
+ - ํ–ฅํ›„ ์—ฐ๊ตฌ ๋ฐฉํ–ฅ์ด๋‚˜ ์‹ค๋ฌด์  ํ•จ์˜ ์ œ์‹œ
429
+ ์ฃผ์˜์‚ฌํ•ญ: ์ „๋ฌธ์„ฑ์„ ์œ ์ง€ํ•˜๋˜, ์™„์ „ํžˆ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์šด ์ˆ˜์ค€์€ ์ง€์–‘
430
+ ์˜ˆ์‹œ: "๋ณธ ์—ฐ๊ตฌ์—์„œ๋Š” ์ธ๊ณต์ง€๋Šฅ(AI)์˜ ์œค๋ฆฌ์  ํ•จ์˜์— ๋Œ€ํ•ด ๊ณ ์ฐฐํ•œ๋‹ค. ํŠนํžˆ, ์ž์œจ์ฃผํ–‰ ์ž๋™์ฐจ์˜ ์˜์‚ฌ๊ฒฐ์ • ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์œค๋ฆฌ์  ๋”œ๋ ˆ๋งˆ์— ์ดˆ์ ์„ ๋งž์ถ˜๋‹ค. Bonnefon et al. (2016)์˜ ์—ฐ๊ตฌ์— ๋”ฐ๋ฅด๋ฉด, ์ž์œจ์ฃผํ–‰ ์ฐจ๋Ÿ‰์˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์ง๋ฉดํ•  ์ˆ˜ ์žˆ๋Š” ์œค๋ฆฌ์  ์„ ํƒ์˜ ๋ณต์žก์„ฑ์ด ์ง€์ ๋œ ๋ฐ” ์žˆ๋‹ค. ๋ณธ๊ณ ์—์„œ๋Š” ์ด๋Ÿฌํ•œ ์œค๋ฆฌ์  ๋”œ๋ ˆ๋งˆ๋ฅผ ์„ธ ๊ฐ€์ง€ ์ฃผ์š” ๊ด€์ ์—์„œ ๋ถ„์„ํ•œ๋‹ค: 1) ๊ณต๋ฆฌ์ฃผ์˜์  ์ ‘๊ทผ, 2) ์˜๋ฌด๋ก ์  ์ ‘๊ทผ, 3) ๋• ์œค๋ฆฌ์  ์ ‘๊ทผ. ๊ฐ ์ ‘๊ทผ๋ฒ•์˜ ์žฅ๋‹จ์ ์„ ๋น„๊ต ๋ถ„์„ํ•˜๊ณ , ์ด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์ž์œจ์ฃผํ–‰ ์ฐจ๋Ÿ‰์˜ ์œค๋ฆฌ์  ์˜์‚ฌ๊ฒฐ์ • ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ œ์•ˆํ•˜๊ณ ์ž ํ•œ๋‹ค...
431
+ """
432
+ }
433
+ return prompts.get(style, "ํฌ์ŠคํŒ… ์Šคํƒ€์ผ ํ”„๋กฌํ”„ํŠธ")
434
+
435
+ # PDF ํด๋ž˜์Šค ์ •์˜
436
+ class PDF(FPDF):
437
+ def __init__(self):
438
+ super().__init__()
439
+ self.add_font("Pretendard", "", FONT_REGULAR_PATH, uni=True)
440
+ self.add_font("Pretendard", "B", FONT_BOLD_PATH, uni=True)
441
+
442
+ def header(self):
443
+ self.set_font("Pretendard", "", 10)
444
+
445
+ def footer(self):
446
+ self.set_y(-15)
447
+ self.set_font("Pretendard", "", 8)
448
+ self.cell(0, 10, f'Page {self.page_no()}', align='C')
449
+
450
+ def save_to_pdf(blog_post, user_topic):
451
+ pdf = PDF()
452
+ pdf.add_page()
453
+
454
+ # HTML์—์„œ ํ…์ŠคํŠธ ์ถ”์ถœ
455
+ soup = BeautifulSoup(blog_post, 'html.parser')
456
+
457
+ # ๋„์ž…๋ถ€ ์ œ๋ชฉ์—์„œ "๋„์ž…๋ถ€:"๋ฅผ ์ œ์™ธํ•˜๊ณ  ์ถ”์ถœ
458
+ title_tag = soup.find("h3")
459
+ title = title_tag.text.replace("๋„์ž…๋ถ€:", "").strip() if title_tag else "๋ธ”๋กœ๊ทธ ๊ธ€"
460
+
461
+ # ํŽ˜์ด์ง€ ๋ฐ ์ด๋ฏธ์ง€ ํฌ๊ธฐ ์„ค์ •
462
+ page_width = pdf.w - 2 * pdf.l_margin
463
+ image_width = page_width
464
+
465
+ # ์ƒ๋‹จ ์ด๋ฏธ์ง€ ๊ฒฝ๋กœ์™€ ๋งํฌ ์„ค์ •
466
+ image_url1 = "https://finalendai.com/wp-content/uploads/2024/10/pdf-banner-top.png"
467
+ image_url2 = "https://finalendai.com/wp-content/uploads/2024/10/pdf-banner-bottom.png"
468
+
469
+ # ์ฒซ ๋ฒˆ์งธ ์ด๋ฏธ์ง€ ์‚ฝ์ž… (์ƒ๋‹จ)
470
+ with urlopen(image_url1) as response:
471
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmp_file:
472
+ tmp_file.write(response.read())
473
+ tmp_file_path = tmp_file.name
474
+
475
+ try:
476
+ img_width, img_height = Image.open(tmp_file_path).size
477
+ ratio = img_height / img_width
478
+ image_height = image_width * ratio
479
+ x = (pdf.w - image_width) / 2
480
+ y = pdf.get_y()
481
+
482
+ pdf.link(x, y, image_width, image_height, "https://finalendai.com")
483
+ pdf.image(tmp_file_path, x=x, y=y, w=image_width)
484
+ pdf.ln(image_height + 10)
485
+ finally:
486
+ os.unlink(tmp_file_path)
487
+
488
+ # ์ œ๋ชฉ ์ถœ๋ ฅ (ํ•œ ๋ฒˆ๋งŒ)
489
+ pdf.set_font("Pretendard", "B", 16)
490
+ pdf.multi_cell(0, 10, title, align='C')
491
+ pdf.ln(10)
492
+
493
+ # ๋ณธ๋ฌธ ๋‚ด์šฉ ์ถ”๊ฐ€
494
+ pdf.set_font("Pretendard", "", 12)
495
+ for tag in soup.find_all(["h2", "h3", "p", "ul", "li"]):
496
+ if tag.name == "h2":
497
+ pdf.set_font("Pretendard", "B", 14)
498
+ pdf.multi_cell(0, 8, tag.get_text().strip())
499
+ pdf.ln(4)
500
+ elif tag.name == "h3":
501
+ pdf.set_font("Pretendard", "B", 12)
502
+ pdf.multi_cell(0, 6, tag.get_text().strip())
503
+ pdf.ln(3)
504
+ elif tag.name == "p":
505
+ pdf.set_font("Pretendard", "", 12)
506
+ pdf.multi_cell(0, 8, tag.get_text().strip())
507
+ pdf.ln(4)
508
+ elif tag.name == "ul" or tag.name == "li":
509
+ pdf.set_font("Pretendard", "", 12)
510
+ pdf.multi_cell(0, 8, f"โ€ข {tag.get_text().strip()}")
511
+ pdf.ln(4)
512
+
513
+ # ํ•˜๋‹จ ์ด๋ฏธ์ง€ ์‚ฝ์ž… (๋งํฌ ํฌํ•จ)
514
+ with urlopen(image_url2) as response:
515
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmp_file:
516
+ tmp_file.write(response.read())
517
+ tmp_file_path = tmp_file.name
518
+
519
+ try:
520
+ if pdf.get_y() + image_height > pdf.page_break_trigger:
521
+ pdf.add_page()
522
+
523
+ x = (pdf.w - image_width) / 2
524
+ y = pdf.get_y()
525
+
526
+ pdf.link(x, y, image_width, image_height, "https://finalendai.com/story/")
527
+ pdf.image(tmp_file_path, x=x, y=y, w=image_width)
528
+ finally:
529
+ os.unlink(tmp_file_path)
530
+
531
+ # ํŒŒ์ผ ์ €์žฅ
532
+ now = datetime.now(ZoneInfo("Asia/Seoul"))
533
+ filename = f"{now.strftime('%y%m%d_%H%M')}_{format_filename(title)}.pdf"
534
+ pdf.output(filename)
535
+ return filename
536
+
537
+
538
+ def format_filename(text):
539
+ text = re.sub(r'[^\w\s-]', '', text)
540
+ return text[:50].strip()
541
+
542
+ def save_content_to_pdf(blog_post, user_topic): # ํ•จ์ˆ˜ ์ˆ˜์ •
543
+ return save_to_pdf(blog_post, user_topic)
544
+
545
+ with gr.Blocks() as demo:
546
+ gr.Markdown(f"# ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŒ… ์ƒ์„ฑ๊ธฐ")
547
+
548
+ gr.Markdown("### 1๋‹จ๊ณ„: ํฌ์ŠคํŒ… ์นดํ…Œ๊ณ ๋ฆฌ๋ฅผ ์ง€์ •ํ•ด์ฃผ์„ธ์š”", elem_id="step-title")
549
+ category = gr.Radio(choices=["์ผ๋ฐ˜", "์ƒํ™œ๊ฑด๊ฐ•"], label="ํฌ์ŠคํŒ… ์นดํ…Œ๊ณ ๋ฆฌ", value="์ผ๋ฐ˜")
550
+
551
+ gr.Markdown("---\n\n")
552
+
553
+ gr.Markdown("### 2๋‹จ๊ณ„: ํฌ์ŠคํŒ… ์Šคํƒ€์ผ์„ ์„ ํƒํ•ด์ฃผ์„ธ์š”", elem_id="step-title")
554
+ style = gr.Radio(choices=["์นœ๊ทผํ•œ", "์ผ๋ฐ˜", "์ „๋ฌธ์ ์ธ"], label="ํฌ์ŠคํŒ… ์Šคํƒ€์ผ", value="์นœ๊ทผํ•œ")
555
+
556
+ gr.Markdown("---\n\n")
557
+
558
+ gr.Markdown("### 3๋‹จ๊ณ„: ์ฐธ๊ณ  ๊ธ€์„ ์ž…๋ ฅํ•˜์„ธ์š”", elem_id="step-title")
559
+ references1 = gr.Textbox(label="์ฐธ๊ณ  ๊ธ€ 1", placeholder="์ฐธ๊ณ ํ•  ๊ธ€์„ ๋ณต์‚ฌํ•˜์—ฌ ๋ถ™์—ฌ๋„ฃ์œผ์„ธ์š”", lines=10)
560
+ references2 = gr.Textbox(label="์ฐธ๊ณ  ๊ธ€ 2", placeholder="์ฐธ๊ณ ํ•  ๊ธ€์„ ๋ณต์‚ฌํ•˜์—ฌ ๋ถ™์—ฌ๋„ฃ์œผ์„ธ์š”", lines=10)
561
+ references3 = gr.Textbox(label="์ฐธ๊ณ  ๊ธ€ 3", placeholder="์ฐธ๊ณ ํ•  ๊ธ€์„ ๋ณต์‚ฌํ•˜์—ฌ ๋ถ™์—ฌ๋„ฃ์œผ์„ธ์š”", lines=10)
562
+
563
+ gr.Markdown("---\n\n")
564
+
565
+ gr.Markdown("### 4๋‹จ๊ณ„: ์•„์›ƒ๋ผ์ธ์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”", elem_id="step-title")
566
+ gr.HTML("<span style='color: grey;'>[์•„์›ƒ๋ผ์ธ์—์„œ ๋‚˜์˜จ ๊ฒฐ๊ณผ๋ฅผ ์ˆ˜์ •ํ•ด์„œ ์‚ฌ์šฉํ•ด์ฃผ์„ธ์š”]</span>")
567
+
568
+ outline_generate_btn = gr.Button("์•„์›ƒ๋ผ์ธ ์ƒ์„ฑํ•˜๊ธฐ")
569
+ outline_result = gr.Textbox(label="์•„์›ƒ๋ผ์ธ ๊ฒฐ๊ณผ", lines=15)
570
+ outline_input = gr.Textbox(label="์ž‘์„ฑํ•  ์•„์›ƒ๋ผ์ธ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”", placeholder="์ƒ์„ฑ๋œ ์•„์›ƒ๋ผ์ธ ๋ณต์‚ฌ, ์ˆ˜์ •ํ•ด์„œ ์‚ฌ์šฉํ•˜์„ธ์š”", lines=10)
571
+
572
+ outline_generate_btn.click(
573
+ fn=generate_outline,
574
+ inputs=[category, style, references1, references2, references3],
575
+ outputs=[outline_result]
576
+ )
577
+
578
+ gr.Markdown("---\n\n")
579
+
580
+ gr.Markdown("### 5๋‹จ๊ณ„: ๊ธ€ ์ƒ์„ฑํ•˜๊ธฐ", elem_id="step-title")
581
+ gr.HTML("<span style='color: grey;'>[์•„์›ƒ๋ผ์ธ์„ ํ™•์ธํ•˜์„ธ์š”]</span>")
582
+
583
+ generate_btn = gr.Button("๋ธ”๋กœ๊ทธ ๊ธ€ ์ƒ์„ฑํ•˜๊ธฐ")
584
+ output = gr.HTML(label="์ƒ์„ฑ๋œ ๋ธ”๋กœ๊ทธ ๊ธ€")
585
+
586
+ generate_btn.click(
587
+ fn=generate_blog_post,
588
+ inputs=[category, style, references1, references2, references3, outline_input],
589
+ outputs=[output],
590
+ show_progress=True
591
+ )
592
+
593
+ save_pdf_btn = gr.Button("PDF๋กœ ์ €์žฅํ•˜๊ธฐ")
594
+ pdf_output = gr.File(label="์ƒ์„ฑ๋œ PDF ํŒŒ์ผ")
595
+
596
+ save_pdf_btn.click(
597
+ fn=save_content_to_pdf,
598
+ inputs=[output],
599
+ outputs=[pdf_output],
600
+ show_progress=True
601
+ )
602
+
603
+ demo.launch()
604
+
605
+ gr.HTML("""
606
+ <style>
607
+ #step-title {
608
+ font-size: 1.7em;
609
+ font-weight: bold;
610
+ }
611
+ </style>
612
+ """)