Create feature_focus_blog.py
Browse files- feature_focus_blog.py +557 -0
feature_focus_blog.py
ADDED
|
@@ -0,0 +1,557 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import random
|
| 3 |
+
import re
|
| 4 |
+
import requests
|
| 5 |
+
import logging
|
| 6 |
+
import tempfile
|
| 7 |
+
from bs4 import BeautifulSoup
|
| 8 |
+
from datetime import datetime
|
| 9 |
+
from zoneinfo import ZoneInfo
|
| 10 |
+
import html
|
| 11 |
+
from PIL import Image
|
| 12 |
+
from urllib.request import urlopen
|
| 13 |
+
import markdown2
|
| 14 |
+
import gradio as gr
|
| 15 |
+
|
| 16 |
+
# ๋ก๊น
์ค์ (INFO ๋ ๋ฒจ)
|
| 17 |
+
logging.basicConfig(level=logging.INFO)
|
| 18 |
+
|
| 19 |
+
# ์์ ์ ์
|
| 20 |
+
TARGET_CHAR_LENGTH = 4000
|
| 21 |
+
MIN_SECTION_LENGTH = 600
|
| 22 |
+
MAX_TOKENS = 15000
|
| 23 |
+
TEMPERATURE = 0.75
|
| 24 |
+
TOP_P = 0.95
|
| 25 |
+
|
| 26 |
+
# API ๊ด๋ จ ์ค์
|
| 27 |
+
gemini_api_key = os.getenv("GEMINI_API_KEY")
|
| 28 |
+
|
| 29 |
+
# --- Google Gemini SDK ์ด๊ธฐํ ---
|
| 30 |
+
from google import genai
|
| 31 |
+
from google.genai import types
|
| 32 |
+
client = genai.Client(api_key=gemini_api_key)
|
| 33 |
+
|
| 34 |
+
# -------------------------------
|
| 35 |
+
# ๊ธฐ๋ณธ ๋์ฐ๋ฏธ ํจ์๋ค
|
| 36 |
+
# -------------------------------
|
| 37 |
+
|
| 38 |
+
def remove_unwanted_phrases(text):
|
| 39 |
+
"""๋ถํ์ํ ํํ ์ ๊ฑฐ ํจ์"""
|
| 40 |
+
unwanted_phrases = [
|
| 41 |
+
'์ฌ๋ฌ๋ถ', '์ต๊ทผ', '๋ง์ง๋ง์ผ๋ก', '๊ฒฐ๋ก ์ ์ผ๋ก', '๊ฒฐ๊ตญ',
|
| 42 |
+
'์ข
ํฉ์ ์ผ๋ก', '๋ฐ๋ผ์', '๋ง๋ฌด๋ฆฌ', '๋์ผ๋ก', '์์ฝ',
|
| 43 |
+
'ํ ์ค ์์ฝ', '์ ๋ฆฌํ์๋ฉด', '์ด์ ๋ฆฌ', '๊ธ์ ๋ง์น๋ฉฐ',
|
| 44 |
+
'์ด์์ผ๋ก', '์ถ์ฒ๋๋ฆฝ๋๋ค', '์ฐธ๊ณ ํ์ธ์', '๋์์ด ๋์
จ๊ธธ',
|
| 45 |
+
'์ข์ ํ๋ฃจ ๋์ธ์', '๋ค์ ๊ธ์์', '๋์์ด ๋์๊ธธ',
|
| 46 |
+
'์ฆ๊ฑฐ์ด ํ๋ฃจ ๋์ธ์', '๊ฐ์ฌํฉ๋๋ค'
|
| 47 |
+
]
|
| 48 |
+
|
| 49 |
+
# ๋ฌธ๋จ๋ณ๋ก ๋๋์ด ์ฒ๋ฆฌ
|
| 50 |
+
lines = text.split('\n')
|
| 51 |
+
result_lines = []
|
| 52 |
+
|
| 53 |
+
for line in lines:
|
| 54 |
+
if "๋ค์ ์น์
์์๋" in line:
|
| 55 |
+
parts = line.split("๋ค์ ์น์
์์๋")
|
| 56 |
+
if parts[0].strip():
|
| 57 |
+
result_lines.append(parts[0].strip())
|
| 58 |
+
else:
|
| 59 |
+
# ๋ถํ์ํ ํํ ์ ๊ฑฐ (๊ตฌ๋์ ํฌํจ)
|
| 60 |
+
for phrase in unwanted_phrases:
|
| 61 |
+
# ๋ถํ์ํ ํํ ์๋ค์ ๊ตฌ๋์ ๊ณผ ๊ณต๋ฐฑ๊น์ง ํฌํจํ์ฌ ์ ๊ฑฐ
|
| 62 |
+
pattern = rf'(\b{re.escape(phrase)}\b[\s,.!?]*)|([,.!?]*\b{re.escape(phrase)}\b)'
|
| 63 |
+
line = re.sub(pattern, '', line)
|
| 64 |
+
|
| 65 |
+
# ๋ฌธ์ฅ ๋ด ์์ฌ ๊ณต๋ฐฑ ๋ฐ ๊ตฌ๋์ ์ ๋ฆฌ
|
| 66 |
+
line = re.sub(r'\s{2,}', ' ', line) # ์ฐ์ ๊ณต๋ฐฑ ์ ๊ฑฐ
|
| 67 |
+
line = line.strip() # ์๋ค ๊ณต๋ฐฑ ์ ๊ฑฐ
|
| 68 |
+
result_lines.append(line)
|
| 69 |
+
|
| 70 |
+
return '\n'.join(result_lines)
|
| 71 |
+
|
| 72 |
+
def convert_to_html(text):
|
| 73 |
+
"""๋งํฌ๋ค์ด ํ์์ HTML๋ก ๋ณํ - ๊ฐ์ ๋ ๋ฒ์ """
|
| 74 |
+
# ์ ๋ชฉ ํ์ ๋ณํ (# -> h1, ## -> h2, ๋ฑ)
|
| 75 |
+
for i in range(6, 0, -1):
|
| 76 |
+
pattern = r'^' + r'#' * i + r'\s+(.+)$'
|
| 77 |
+
text = re.sub(pattern, r'<h' + str(i) + r'>\1</h' + str(i) + r'>', text, flags=re.MULTILINE)
|
| 78 |
+
|
| 79 |
+
# ๋ณผ๋์ฒด ๋ณํ (**text** -> <strong>text</strong>)
|
| 80 |
+
text = re.sub(r'\*\*(.+?)\*\*', r'<strong>\1</strong>', text)
|
| 81 |
+
|
| 82 |
+
# ์ดํค๋ฆญ์ฒด ๋ณํ (*text* -> <em>text</em>)
|
| 83 |
+
text = re.sub(r'\*([^*]+?)\*', r'<em>\1</em>', text)
|
| 84 |
+
|
| 85 |
+
# ๋ชฉ๋ก ๋ณํ (- item -> <li>item</li>)
|
| 86 |
+
lines = text.split('\n')
|
| 87 |
+
in_list = False
|
| 88 |
+
result_lines = []
|
| 89 |
+
|
| 90 |
+
for line in lines:
|
| 91 |
+
list_match = re.match(r'^[\*\-+]\s+(.+)$', line)
|
| 92 |
+
if list_match:
|
| 93 |
+
if not in_list:
|
| 94 |
+
result_lines.append('<ul>')
|
| 95 |
+
in_list = True
|
| 96 |
+
result_lines.append(f'<li>{list_match.group(1)}</li>')
|
| 97 |
+
else:
|
| 98 |
+
if in_list:
|
| 99 |
+
result_lines.append('</ul>')
|
| 100 |
+
in_list = False
|
| 101 |
+
|
| 102 |
+
# ๋จ๋ฝ ์ฒ๋ฆฌ
|
| 103 |
+
if line.strip() and not re.match(r'^<h[1-6]>|<ul>|<li>|<\/ul>|<\/li>', line):
|
| 104 |
+
result_lines.append(f'<p>{line}</p>')
|
| 105 |
+
elif not line.strip():
|
| 106 |
+
result_lines.append('<br>')
|
| 107 |
+
else:
|
| 108 |
+
result_lines.append(line)
|
| 109 |
+
|
| 110 |
+
if in_list:
|
| 111 |
+
result_lines.append('</ul>')
|
| 112 |
+
|
| 113 |
+
# ์ต์ข
HTML ๊ฒฐํฉ
|
| 114 |
+
html_content = '\n'.join(result_lines)
|
| 115 |
+
|
| 116 |
+
# HTML ์คํ์ผ ์ ์ฉ (์ ๋ชฉ๊ณผ ์์ฌ๋ชฉ์ Bold ๋ฐ ํฐํธ ์ง์ )
|
| 117 |
+
styled_html = f"""
|
| 118 |
+
<div style="font-family: 'Pretendard', Arial, sans-serif; color: #333; line-height: 1.6;">
|
| 119 |
+
<style>
|
| 120 |
+
h1 {{
|
| 121 |
+
font-size: 1.8em;
|
| 122 |
+
margin-top: 1.5em;
|
| 123 |
+
margin-bottom: 0.8em;
|
| 124 |
+
color: #111;
|
| 125 |
+
font-weight: bold;
|
| 126 |
+
font-family: 'Pretendard', Arial, sans-serif;
|
| 127 |
+
}}
|
| 128 |
+
h2 {{
|
| 129 |
+
font-size: 1.5em;
|
| 130 |
+
margin-top: 1.3em;
|
| 131 |
+
margin-bottom: 0.7em;
|
| 132 |
+
color: #222;
|
| 133 |
+
font-weight: bold;
|
| 134 |
+
font-family: 'Pretendard', Arial, sans-serif;
|
| 135 |
+
}}
|
| 136 |
+
h3 {{
|
| 137 |
+
font-size: 1.3em;
|
| 138 |
+
margin-top: 1.1em;
|
| 139 |
+
margin-bottom: 0.6em;
|
| 140 |
+
color: #333;
|
| 141 |
+
font-weight: bold;
|
| 142 |
+
font-family: 'Pretendard', Arial, sans-serif;
|
| 143 |
+
}}
|
| 144 |
+
p {{
|
| 145 |
+
margin-bottom: 1em;
|
| 146 |
+
line-height: 1.7;
|
| 147 |
+
font-size: 1.05em;
|
| 148 |
+
}}
|
| 149 |
+
strong {{
|
| 150 |
+
font-weight: bold;
|
| 151 |
+
color: #000;
|
| 152 |
+
}}
|
| 153 |
+
em {{
|
| 154 |
+
font-style: italic;
|
| 155 |
+
}}
|
| 156 |
+
ul {{
|
| 157 |
+
margin-left: 1.5em;
|
| 158 |
+
margin-bottom: 1em;
|
| 159 |
+
}}
|
| 160 |
+
li {{
|
| 161 |
+
margin-bottom: 0.5em;
|
| 162 |
+
}}
|
| 163 |
+
</style>
|
| 164 |
+
{html_content}
|
| 165 |
+
</div>
|
| 166 |
+
"""
|
| 167 |
+
|
| 168 |
+
return styled_html
|
| 169 |
+
|
| 170 |
+
def post_process_blog(blog_content, style="์น๊ทผํ"):
|
| 171 |
+
"""๋ธ๋ก๊ทธ ์ปจํ
์ธ ํ์ฒ๋ฆฌ ํจ์"""
|
| 172 |
+
try:
|
| 173 |
+
# ๋งํฌ๋ค์ด ์ ๊ฑฐ (# ํ์์ ์ ๋ชฉ ์ ์ธ)
|
| 174 |
+
blog_content = re.sub(r'^\s*[\*\-+]\s+', '- ', blog_content, flags=re.MULTILINE) # ๊ธ๋จธ๋ฆฌ ๊ธฐํธ ํต์ผ
|
| 175 |
+
|
| 176 |
+
# ์คํ์ผ์ ๋ฐ๋ฅธ ์ดํฌ ์กฐ์
|
| 177 |
+
if style == "์น๊ทผํ":
|
| 178 |
+
blog_content = re.sub(r'([๊ฐ-ํฃ]+)๊ณ ์', r'\1๊ตฌ์', blog_content)
|
| 179 |
+
blog_content = re.sub(r'๋ต๋๋ค', '์ด์', blog_content)
|
| 180 |
+
blog_content = re.sub(r'์๋ต๋๋ค', '์์ด์', blog_content)
|
| 181 |
+
blog_content = re.sub(r'ํ๋ต๋๋ค', 'ํ์ด์', blog_content)
|
| 182 |
+
blog_content = re.sub(r'์ต๋๋ค', '์', blog_content)
|
| 183 |
+
blog_content = re.sub(r'ํฉ๋๋ค', 'ํด์', blog_content)
|
| 184 |
+
blog_content = re.sub(r'๋ฉ๋๋ค', '๋ผ์', blog_content)
|
| 185 |
+
blog_content = re.sub(r'์
๋๋ค', '์ด์์', blog_content)
|
| 186 |
+
|
| 187 |
+
# ํต์ฌ๊ธฐ๋ฅ ์ ๋ฌธ์ฉ์ด ๊ฐํ ๋ฐ ๊ตฌ์ฒด์ ์์น ๊ฐ์กฐ
|
| 188 |
+
tech_terms = [
|
| 189 |
+
(r'์ฑ๋ฅ\b(?!\s*๋ถ์|\s*ํ
์คํธ|\s*์ธก์ )', r'๊ธฐ์ ์ ์ฑ๋ฅ'),
|
| 190 |
+
(r'์๋\b(?!\s*์ธก์ |\s*ํ
์คํธ)', r'์ฒ๋ฆฌ ์๋'),
|
| 191 |
+
(r'ํ๋ฉด\b(?!\s*ํฌ๊ธฐ|\s*๋ฐ๊ธฐ)', r'๋์คํ๋ ์ด'),
|
| 192 |
+
(r'์นด๋ฉ๋ผ\b(?!\s*๋ชจ๋|\s*์ผ์)', r'์ด๋ฏธ์ง ์ผ์ ์์คํ
'),
|
| 193 |
+
(r'๋ฐฐํฐ๋ฆฌ\b(?!\s*์ฉ๋|\s*์๋ช
)', r'์ ๋ ฅ ๊ด๋ฆฌ ์์คํ
'),
|
| 194 |
+
(r'์ฌ์ฉ\b(?!\s*๋ฐฉ๋ฒ|\s*์ค๋ช
|\s*์ฌ๋ก)', r'์ด์ฉ'),
|
| 195 |
+
(r'์ข๋ค\b(?!\s*๊ณ )', r'ํจ์จ์ ์ด๋ค'),
|
| 196 |
+
(r'๋น ๋ฅด๋ค\b', r'๊ณ ์ฑ๋ฅ์ด๋ค')
|
| 197 |
+
]
|
| 198 |
+
|
| 199 |
+
for pattern, replacement in tech_terms:
|
| 200 |
+
blog_content = re.sub(pattern, replacement, blog_content)
|
| 201 |
+
|
| 202 |
+
# ๋ถ์์ ํํ ๊ฐํ
|
| 203 |
+
blog_content = re.sub(r'์ ์๊ฐ์๋', r'๋ถ์ ๊ฒฐ๊ณผ์ ๋ฐ๋ฅด๋ฉด', blog_content)
|
| 204 |
+
blog_content = re.sub(r'์ ๊ฐ ๋ดค์ ๋', r'๊ธฐ์ ์ ๊ด์ ์์', blog_content)
|
| 205 |
+
blog_content = re.sub(r'๋๋์ด ๋ค์ด์', r'ํ์ธ๋ฉ๋๋ค', blog_content)
|
| 206 |
+
|
| 207 |
+
# ์์น์ ๋จ์ ์ฌ์ด์ ๊ณต๋ฐฑ ์ถ๊ฐ ๋ฐ ๊ฐ์กฐ
|
| 208 |
+
def add_space_to_numbers(match):
|
| 209 |
+
number, unit = match.groups()
|
| 210 |
+
return f"{number} {unit}"
|
| 211 |
+
|
| 212 |
+
blog_content = re.sub(r'(\d+(?:\.\d+)?)([๊ฐ-ํฃ]+)', add_space_to_numbers, blog_content)
|
| 213 |
+
|
| 214 |
+
# ์ฃผ์ ์ซ์ ๋ฐ์ดํฐ ๋ณผ๋ ์ฒ๋ฆฌ
|
| 215 |
+
blog_content = re.sub(r'(\d+(?:\.\d+)?(?:\s*%|\s*dB|\s*Hz|\s*์๊ฐ|\s*mAh|\s*GB|\s*MB|\s*TB|\s*MP))', r'**\1**', blog_content)
|
| 216 |
+
|
| 217 |
+
# ๊ณผ์ฅ๋ ํํ ์ ๋ฆฌ
|
| 218 |
+
exaggerated_expressions = [
|
| 219 |
+
(r'ํ์์ ์ธ', r'์ค์ํ'),
|
| 220 |
+
(r'ํ๋ช
์ ์ธ', r'์ฃผ๋ชฉํ ๋งํ'),
|
| 221 |
+
(r'๋๋ผ์ด', r'์ฃผ๋ชฉํ ๋งํ'),
|
| 222 |
+
(r'๊ธฐ์ ์', r'ํจ๊ณผ์ ์ธ'),
|
| 223 |
+
(r'์ต๊ณ ์', r'์ฐ์ํ'),
|
| 224 |
+
(r'์ธ๊ณ์ ์ธ', r'์ฃผ์'),
|
| 225 |
+
(r'์๋ฒฝํ', r'์ฐ์ํ'),
|
| 226 |
+
(r'๊ทน์ ์ธ', r'์๋นํ'),
|
| 227 |
+
(r'๋ฌดํํ', r'๋ค์ํ'),
|
| 228 |
+
(r'์ ๋์ ์ธ', r'์ค์ํ'),
|
| 229 |
+
(r'ํ์ ์ ์ธ', r'์๋ก์ด'),
|
| 230 |
+
(r'ํ์์ ์ธ', r'์ฐ์ํ'),
|
| 231 |
+
(r'๊ทผ๋ณธ์ ์ธ', r'๊ธฐ๋ณธ์ ์ธ'),
|
| 232 |
+
(r'ํ๊ธฐ์ ์ธ', r'์ค์ํ'),
|
| 233 |
+
(r'์ ๋ก์๋', r'ํน๋ณํ'),
|
| 234 |
+
(r'์๋์ ์ธ', r'๋๋๋ฌ์ง'),
|
| 235 |
+
(r'๊ธฐ๊ฐ ๋งํ', r'ํจ๊ณผ์ ์ธ'),
|
| 236 |
+
(r'๋ํ์', r'์ต์์ ๋ชจ๋ธ')
|
| 237 |
+
]
|
| 238 |
+
|
| 239 |
+
for pattern, replacement in exaggerated_expressions:
|
| 240 |
+
blog_content = re.sub(r'\b' + pattern + r'\b', replacement, blog_content, flags=re.IGNORECASE)
|
| 241 |
+
|
| 242 |
+
# ์ฐธ๊ณ ๊ธ ๊ด๋ จ ํํ ์ ๋ฆฌ
|
| 243 |
+
blog_content = re.sub(r'์ฐธ๊ณ ๊ธ์ ๋ฐ๋ฅด๋ฉด', r'๊ธฐ์ ๋ถ์์ ๋ฐ๋ฅด๋ฉด', blog_content)
|
| 244 |
+
blog_content = re.sub(r'์ฐธ๊ณ ๊ธ', r'๊ธฐ์ ๋ฌธ์', blog_content)
|
| 245 |
+
|
| 246 |
+
return blog_content
|
| 247 |
+
except Exception as e:
|
| 248 |
+
logging.error(f"๋ธ๋ก๊ทธ ๊ธ ํ์ฒ๋ฆฌ ์ค ์ค๋ฅ ๋ฐ์: {str(e)}")
|
| 249 |
+
return blog_content
|
| 250 |
+
|
| 251 |
+
def generate_outline(category, style, references1, references2, references3):
|
| 252 |
+
"""ํต์ฌ๊ธฐ๋ฅ ์ ๋ณ ํจ์ - ๊ฐ๋จํ ์ค๋ช
์ถ๊ฐ"""
|
| 253 |
+
try:
|
| 254 |
+
# ์ฐธ๊ณ ๊ธ ์ ๋ณด ์ค๋น
|
| 255 |
+
references = [
|
| 256 |
+
references1.strip() if references1.strip() else "์ฐธ๊ณ ์๋ฃ ์์",
|
| 257 |
+
references2.strip() if references2.strip() else "์ฐธ๊ณ ์๋ฃ ์์",
|
| 258 |
+
references3.strip() if references3.strip() else "์ฐธ๊ณ ์๋ฃ ์์"
|
| 259 |
+
]
|
| 260 |
+
|
| 261 |
+
# ์๋ฏธ ์๋ ์ฐธ๊ณ ๊ธ๋ง ํํฐ๋ง
|
| 262 |
+
meaningful_refs = [ref for ref in references if ref != "์ฐธ๊ณ ์๋ฃ ์์"]
|
| 263 |
+
|
| 264 |
+
if not meaningful_refs:
|
| 265 |
+
return ["์ฐธ๊ณ ์๋ฃ๊ฐ ์์ต๋๋ค"] * 5
|
| 266 |
+
|
| 267 |
+
# ์คํ์ผ ํ๋กฌํํธ ๊ฐ์ ธ์ค๊ธฐ
|
| 268 |
+
style_prompt = get_style_prompt(style)
|
| 269 |
+
|
| 270 |
+
# ๋ชจ๋ ์ฐธ๊ณ ๊ธ ๊ฒฐํฉ
|
| 271 |
+
combined_refs = "\n\n".join(meaningful_refs)
|
| 272 |
+
|
| 273 |
+
# LLM์ ํต์ฌ๊ธฐ๋ฅ ์ถ์ถ ์์ฒญ
|
| 274 |
+
extract_prompt = f"""
|
| 275 |
+
[ํต์ฌ๊ธฐ๋ฅ ์ ๋ณ ์์ฒญ]
|
| 276 |
+
์ ๊ณต๋ ์ฐธ๊ณ ๊ธ์์ ๊ฐ์ฅ ์ค์ํ๊ณ ํต์ฌ์ ์ธ ๊ธฐ๋ฅ 5๊ฐ์ง๋ฅผ ์ ๋ณํ๊ณ ๊ฐ๊ฐ์ ๊ฐ๋จํ ์ค๋ช
์ ์ถ๊ฐํด์ฃผ์ธ์.
|
| 277 |
+
|
| 278 |
+
์ฐธ๊ณ ๊ธ:
|
| 279 |
+
{combined_refs}
|
| 280 |
+
|
| 281 |
+
[์์คํ
์ญํ ]
|
| 282 |
+
๋น์ ์ ์๋
๊ฐ์ ๊ฒฝํ์ ๊ฐ์ง ์ํ ๊ธฐ๋ฅ ์ ๋ฌธ ๋ถ์๊ฐ์
๋๋ค. ์ ํ์ ๋จ์ผ ํต์ฌ ๊ธฐ๋ฅ์ ์ฌ์ธต์ ์ผ๋ก ๋ถ์ํ๊ณ ๋ค์ํ ์ธก๋ฉด์์ ํ๊ฐํ์ฌ ๋ง์ ๋
์๋ค์ ์ ๋ขฐ๋ฅผ ๋ฐ๊ณ ์์ต๋๋ค.
|
| 283 |
+
|
| 284 |
+
[๋ถ์ ๋จ๊ณ]
|
| 285 |
+
1. ์ฐธ๊ณ ์๋ฃ 3๊ฐ๋ฅผ ์ฒ ์ ํ ๋ถ์ํ์ฌ ์ ํ์ ๋จ์ผ ํต์ฌ ๊ธฐ๋ฅ ์๋ณ
|
| 286 |
+
2. ์ ์ ํ ํต์ฌ ๊ธฐ๋ฅ์ 5๊ฐ์ง ์ฃผ์ ์ธก๋ฉด ํ์
(์ฑ๋ฅ, ์ฌ์ฉ์ฑ, ํจ์จ์ฑ, ๊ธฐ์ ์ ํน์ง, ํ์ฉ ๊ฐ์น ๋ฑ)
|
| 287 |
+
3. ์ ์ ํ ํต์ฌ ๊ธฐ๋ฅ์ด ์ ํ ์ ์ฒด์์ ๊ฐ๋ ์ค์๋์ ์ฐจ๋ณ์ฑ ํ๊ฐ
|
| 288 |
+
|
| 289 |
+
[์์๋ผ์ธ ๊ตฌ์ฑ ์์น]
|
| 290 |
+
1. ๋ณธ๋ก (5๊ฐ) - ์ฐธ๊ณ ์๋ฃ ๋ถ์์ ํตํด ๋ฐ๊ฒฌํ ํต์ฌ ๊ธฐ๋ฅ์ 5๊ฐ์ง ์ค์ ์ธก๋ฉด์ ๋ด์ ์์ ๋ชฉ
|
| 291 |
+
- ํต์ฌ ๊ธฐ๋ฅ์ ๊ธฐ์ ์ ์๋ฆฌ์ ์๋ ๋ฉ์ปค๋์ฆ
|
| 292 |
+
- ํต์ฌ ๊ธฐ๋ฅ์ ์ค์ ์ฑ๋ฅ ๋ฐ ์ธก์ ๋ฐ์ดํฐ ๋ถ์
|
| 293 |
+
- ์ฌ์ฉ์ ๊ฒฝํ ์ธก๋ฉด์์์ ๊ธฐ๋ฅ ํ๊ฐ
|
| 294 |
+
- ๊ฒฝ์ ์ ํ๊ณผ์ ํด๋น ๊ธฐ๋ฅ ๋น๊ต ๋ถ์
|
| 295 |
+
- ํต์ฌ ๊ธฐ๋ฅ์ ์ค์ํ ํ์ฉ ๊ฐ์น์ ํ๊ณ์
|
| 296 |
+
- (์ ํญ๋ชฉ๋ค์ ์ ์ ๋ ํต์ฌ ๊ธฐ๋ฅ์ ๋ฐ๋ผ ์ ์ฐํ๊ฒ ์กฐ์ )
|
| 297 |
+
|
| 298 |
+
[ํต์ฌ ์ง์นจ]
|
| 299 |
+
1. ์์ ํ ํ๊ตญ์ด๋ก๋ง ์์ฑํ ๊ฒ
|
| 300 |
+
2. ์์ ๋ชฉ์ ์ต๋ 30์ ์ด๋ด๋ก ๊ฐ๊ฒฐํ๊ฒ ์์ฑ
|
| 301 |
+
3. ์ ์ ๋ ํต์ฌ ๊ธฐ๋ฅ์ ์ค์ ์ธก๋ฉด์ ๋ช
ํํ ๋๋ฌ๋ด๋ ํํ ์ฌ์ฉ (์: "์ ๋ฐ ์ธก์ ์คํ์ผ๋ก ๋ณธ ์ฑ๋ฅ ํ๊ณ", "์ผ์ ํ๊ฒฝ์์์ ๊ธฐ๋ฅ ์์ ์ฑ ๋ถ์")
|
| 302 |
+
4. ๊ธฐ์ ์ ์ ํ์ฑ๊ณผ ์ฌ์ธต์ ๋ถ์์ด ์์ ๋ชฉ์ ๋ฐ์๋๋๋ก ๊ตฌ์ฑ
|
| 303 |
+
5. ํค์๋๋ ์์ ๋ชฉ ๊ฒฐ์ ์ ์ํฅ์ ์ฃผ์ง ์์ (๋ณธ๋ฌธ ์์ฑ ์ ์ฐธ๊ณ ์ฌํญ์ผ๋ก๋ง ํ์ฉ)
|
| 304 |
+
6. ๋ณธ๋ก 5๊ฐ ํญ๋ชฉ๋ง์ผ๋ก ๊ตฌ์ฑ (๋์
๋ถ์ ๊ฒฐ๋ก ๋ถํ์)
|
| 305 |
+
7. ๋ค์ํ ์ ํ ์นดํ
๊ณ ๋ฆฌ์ ๋จ์ผ ๊ธฐ๋ฅ ๋ถ์์ ์ ์ฐํ๊ฒ ์ ์ฉํ ์ ์๋๋ก ๊ตฌ์ฑ
|
| 306 |
+
8. ํน์๋ฌธ์(**, :, #, ## ๋ฑ)๋ฅผ ์ฌ์ฉํ์ง ๋ง๊ณ ์ผ๋ฐ ํ
์คํธ๋ก๋ง ์์ฑํ์ธ์.
|
| 307 |
+
|
| 308 |
+
[์ถ๋ ฅ ํ์]
|
| 309 |
+
1. ์ฐธ๊ณ ์๋ฃ ๋ถ์์ ํตํด ์ ์ ๋ ํต์ฌ ๊ธฐ๋ฅ์ 5๊ฐ์ง ์ค์ ์ธก๋ฉด์ ํ์
ํ์ฌ ์์ ๋กญ๊ฒ ์์๋ผ์ธ ๊ตฌ์ฑ
|
| 310 |
+
2. ๋ฐ๋์ ๋ณธ๋ก 5๊ฐ ํญ๋ชฉ์ผ๋ก๋ง ๊ตฌ์ฑํ ๊ฒ:(๊ฐ ํญ๋ชฉ๋น 1๋ฒ ์ํฐ๋ฅผ ์ ์ฉํ์ฌ ๋น์นธ์ด ๋์ค์ง ์๋๋กํ๋ผ.)
|
| 311 |
+
- ๋ณธ๋ก 1: [ํต์ฌ ๊ธฐ๋ฅ์ ๊ธฐ์ ์ ์๋ฆฌ/์๋ ๋ฉ์ปค๋์ฆ ๊ด๋ จ ์ ๋ชฉ]
|
| 312 |
+
- ๋ณธ๋ก 2: [ํต์ฌ ๊ธฐ๋ฅ์ ์ฑ๋ฅ/์ธก์ ๋ฐ์ดํฐ ๊ด๋ จ ์ ๋ชฉ]
|
| 313 |
+
- ๋ณธ๋ก 3: [์ฌ์ฉ์ ๊ฒฝํ ์ธก๋ฉด์ ๊ธฐ๋ฅ ํ๊ฐ ๊ด๋ จ ์ ๋ชฉ]
|
| 314 |
+
- ๋ณธ๋ก 4: [๊ฒฝ์ ์ ํ๊ณผ์ ๊ธฐ๋ฅ ๋น๊ต ๊ด๋ จ ์ ๋ชฉ]
|
| 315 |
+
- ๋ณธ๋ก 5: [์ค์ํ ํ์ฉ ๊ฐ์น/ํ๊ณ์ ๊ด๋ จ ์ ๋ชฉ]
|
| 316 |
+
3. ์์ ๋ชฉ์ ์ ์ ๋ ํต์ฌ ๊ธฐ๋ฅ์ ํน์ฑ์ ๋ง๊ฒ ์์ ๋กญ๊ฒ ๊ตฌ์ฑ
|
| 317 |
+
4. ํค์๋์ ๋ง์ถ์ง ๋ง๊ณ , ์ฐธ๊ณ ์๋ฃ ๋ถ์์ ํตํด ๋ฐ๊ฒฌํ ํต์ฌ ๊ธฐ๋ฅ์ ์ค์ ์ธก๋ฉด ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ฑ
|
| 318 |
+
5. ์์ ํ์ (์ฐธ๊ณ ์ฉ์ผ ๋ฟ, ๋ด์ฉ์ ์ ์ ๋ ํต์ฌ ๊ธฐ๋ฅ๊ณผ ์ฐธ๊ณ ์๋ฃ์ ๋ฐ๋ผ ์์ ํ ๋ฌ๋ผ์ง ์ ์์):
|
| 319 |
+
- ๋ณธ๋ก 1: [ํต์ฌ ๊ธฐ๋ฅ์ ๊ธฐ์ ์ ์๋ฆฌ/๋ฉ์ปค๋์ฆ ๊ด๋ จ ์ ๋ชฉ]
|
| 320 |
+
- ๋ณธ๋ก 2: [์ค์ธก ํ
์คํธ ๊ฒฐ๊ณผ/์ฑ๋ฅ ๋ฐ์ดํฐ ๊ด๋ จ ์ ๋ชฉ]
|
| 321 |
+
- ๋ณธ๋ก 3: [์ค์ฌ์ฉ ํ๊ฒฝ์์์ ์ฌ์ฉ์ฑ/ํจ์จ์ฑ ๊ด๋ จ ์ ๋ชฉ]
|
| 322 |
+
- ๋ณธ๋ก 4: [ํ ์ ํ ๋์ผ ๊ธฐ๋ฅ๊ณผ์ ์ฐจ๋ณ์ ๊ด๋ จ ์ ๋ชฉ]
|
| 323 |
+
- ๋ณธ๋ก 5: [๊ธฐ๋ฅ์ ๋ฏธ๋ ๋ฐ์ ๊ฐ๋ฅ์ฑ/๊ฐ์ ์ ๊ด๋ จ ์ ๋ชฉ]
|
| 324 |
+
|
| 325 |
+
{style_prompt}
|
| 326 |
+
"""
|
| 327 |
+
|
| 328 |
+
# Gemini API ํธ์ถ
|
| 329 |
+
outline_result = call_gemini_api(extract_prompt, temperature=0.3)
|
| 330 |
+
|
| 331 |
+
# ๊ฒฐ๊ณผ์์ ํต์ฌ๊ธฐ๋ฅ ์ถ์ถ
|
| 332 |
+
features = []
|
| 333 |
+
for line in outline_result.strip().split('\n'):
|
| 334 |
+
if line.strip():
|
| 335 |
+
# ํน์๋ฌธ์์ ๋ถํ์ํ ํ์ ์ ๊ฑฐ
|
| 336 |
+
clean_feature = re.sub(r'^\s*[-*#]\s*', '', line) # ๋ฒํธ, ๋ถ๋ฆฟ ์ ๊ฑฐ
|
| 337 |
+
clean_feature = re.sub(r'\*\*|\*|##|#', '', clean_feature) # ํน์๋ฌธ์ ์ ๊ฑฐ
|
| 338 |
+
clean_feature = clean_feature.strip()
|
| 339 |
+
|
| 340 |
+
if clean_feature:
|
| 341 |
+
features.append(clean_feature)
|
| 342 |
+
|
| 343 |
+
# 5๊ฐ๊ฐ ์ ๋๋ฉด ๋น ๊ฐ์ผ๋ก ์ฑ์ฐ๊ธฐ
|
| 344 |
+
while len(features) < 5:
|
| 345 |
+
features.append(f"ํน์ง {len(features) + 1} - ์ถ๊ฐ ์ค๋ช
ํ์")
|
| 346 |
+
|
| 347 |
+
return features[:5] # ์ต๋ 5๊ฐ๋ง ๋ฐํ
|
| 348 |
+
|
| 349 |
+
except Exception as e:
|
| 350 |
+
logging.error(f"ํต์ฌ๊ธฐ๋ฅ ์ ๋ณ ์ค ์ค๋ฅ ๋ฐ์: {str(e)}")
|
| 351 |
+
return ["ํน์ง์ ์ถ์ถํ์ง ๋ชปํ์ต๋๋ค"] * 5
|
| 352 |
+
|
| 353 |
+
def generate_blog_post(category, style, references1, references2, references3, selected_feature):
|
| 354 |
+
"""ํต์ฌ๊ธฐ๋ฅ์ง์คํ ๋ธ๋ก๊ทธ ๊ธ ์์ฑ ํจ์ - ์ ์ฐํ ์์ฌ ๊ตฌ์ฑ"""
|
| 355 |
+
try:
|
| 356 |
+
# ์ฐธ๊ณ ๊ธ ์ค๋น
|
| 357 |
+
references = [
|
| 358 |
+
references1.strip() if references1.strip() else "์ฐธ๊ณ ์๋ฃ ์์",
|
| 359 |
+
references2.strip() if references2.strip() else "์ฐธ๊ณ ์๋ฃ ์์",
|
| 360 |
+
references3.strip() if references3.strip() else "์ฐธ๊ณ ์๋ฃ ์์"
|
| 361 |
+
]
|
| 362 |
+
|
| 363 |
+
# ์๋ฏธ ์๋ ์ฐธ๊ณ ๊ธ๋ง ํํฐ๋ง
|
| 364 |
+
references = [ref for ref in references if ref != "์ฐธ๊ณ ์๋ฃ ์์"]
|
| 365 |
+
|
| 366 |
+
if not references:
|
| 367 |
+
return "<p>์ฐธ๊ณ ์๋ฃ๊ฐ ์์ต๋๋ค. ์ต์ ํ๋ ์ด์์ ์ฐธ๊ณ ์๋ฃ๋ฅผ ์
๋ ฅํด์ฃผ์ธ์.</p>"
|
| 368 |
+
|
| 369 |
+
if not selected_feature.strip():
|
| 370 |
+
return "<p>ํต์ฌ๊ธฐ๋ฅ์ด ์ ํ๋์ง ์์์ต๋๋ค. ํต์ฌ๊ธฐ๋ฅ์ ์
๋ ฅํด์ฃผ์ธ์.</p>"
|
| 371 |
+
|
| 372 |
+
# ์คํ์ผ ํ๋กฌํํธ ๊ฐ์ ธ์ค๊ธฐ
|
| 373 |
+
style_prompt = get_style_prompt(style)
|
| 374 |
+
|
| 375 |
+
# ๋ธ๋ก๊ทธ ๊ธ ์์ฑ ํ๋กฌํํธ ๊ตฌ์ฑ
|
| 376 |
+
blog_prompt = f"""
|
| 377 |
+
[ํต์ฌ๊ธฐ๋ฅ ์ง์คํ ์ํ๋ฆฌ๋ทฐ ์์ฑ ์์ฒญ]
|
| 378 |
+
์ ํํ ํต์ฌ๊ธฐ๋ฅ: {selected_feature}
|
| 379 |
+
|
| 380 |
+
[๋ฆฌ๋ทฐ ์์ฑ ํ์]
|
| 381 |
+
1. ๋ฆฌ๋ทฐ๋ '๋์
๋ถ', '5๊ฐ์ง ์์ฌ', '๋ง๋ฌด๋ฆฌ' ๊ตฌ์กฐ๋ก ์์ฑํ์ธ์.
|
| 382 |
+
2. ๋งํฌ๋ค์ด ํ์์ ์ต์ํ์ผ๋ก ์ฌ์ฉํ๊ณ , ๊ฐ๋ฅํ ํ ์ผ๋ฐ ํ
์คํธ๋ก ์์ฑํ์ธ์.
|
| 383 |
+
3. ๊ฐ ๋ถ๋ถ์ ๋ช
ํํ ๊ตฌ๋ถ๋์ด์ผ ํ๋ฉฐ, ์์ ํ ๋ฌธ์ฅ์ผ๋ก ์์ฐ์ค๋ฝ๊ฒ ์ด์ด์ง๋๋ก ์์ฑํ์ธ์.
|
| 384 |
+
4. ๋จ๋ฝ์ ์ ์ ํ ๋๋๋, ๋๋ฌด ์งง์ ๋จ๋ฝ์ ๋ง์ด ๋ง๋ค์ง ๋ง์ธ์.
|
| 385 |
+
|
| 386 |
+
[๋ฆฌ๋ทฐ ๋ด์ฉ ๊ตฌ์กฐ]
|
| 387 |
+
1. ๋์
๋ถ (์ ์ฒด์ 10%)
|
| 388 |
+
- ์ ํํ ํต์ฌ๊ธฐ๋ฅ์ ์ค์์ฑ๊ณผ ํน์ง์ ๊ฐ๋ตํ ์๊ฐ
|
| 389 |
+
- ์ด ๊ธฐ๋ฅ์ด ์ํ์์ ์ด๋ค ๊ฐ์น๋ฅผ ์ ๊ณตํ๋์ง ์ค๋ช
|
| 390 |
+
- ๋ง์ง๋ง ๋ฌธ์ฅ์์ ๋ณธ๋ฌธ์์ ๋ค๋ฃฐ ๋ด์ฉ์ ์๊ณ
|
| 391 |
+
|
| 392 |
+
2. 5๊ฐ์ง ์์ฌ (์ ์ฒด์ 80%)
|
| 393 |
+
- ์ ํํ ํต์ฌ๊ธฐ๋ฅ์ ๊ฐ์ฅ ์ ํฉํ 5๊ฐ์ง ์์ฌ๋ฅผ ์์ ๋กญ๊ฒ ์ ์ ํ์ธ์
|
| 394 |
+
- ๊ฐ ์์ฌ๋ ๊ธฐ๋ฅ์ ์๋ก ๋ค๋ฅธ ์ธก๋ฉด์ ๋ค๋ฃจ์ด์ผ ํฉ๋๋ค
|
| 395 |
+
- ์์ ์์ฌ: ๊ธฐ์ ์ ์๋ฆฌ, ์๋ ๋ฐฉ์, ์ฑ๋ฅ ๋ถ์, ๊ฒฝ์ ์ ํ ๋น๊ต, ํ์ฉ ๋ฐฉ๋ฒ, ์ฌ์ฉ ๊ฒฝํ, ์ค์ ํ,
|
| 396 |
+
์
๋ฐ์ดํธ ์ด๋ ฅ, ์ฐ์
ํ์ค๊ณผ์ ๋น๊ต, ์ฌ์ฉ ์๋๋ฆฌ์ค, ํธํ์ฑ, ํ๊ณ์ ๊ณผ ๊ฐ์ ๋ฐฉํฅ ๋ฑ
|
| 397 |
+
- ๊ฐ ์์ฌ๋ ๋น์ทํ ๋ถ๋์ผ๋ก ์์ฐ์ค๋ฝ๊ฒ ์ฐ๊ฒฐ๋์ด์ผ ํฉ๋๋ค
|
| 398 |
+
|
| 399 |
+
3. ๋ง๋ฌด๋ฆฌ (์ ์ฒด์ 10%)
|
| 400 |
+
- ์ด ๊ธฐ๋ฅ์ ์ข
ํฉ์ ํ๊ฐ์ ๊ฐ์น
|
| 401 |
+
- ์ด๋ค ์ ํ์ ์ฌ์ฉ์์๊ฒ ํนํ ์ ์ฉํ์ง
|
| 402 |
+
- ํต์ฌ๊ธฐ๋ฅ๊ณผ ์ ํ ์ ์ฒด์ ๋ํ ์ต์ข
๊ฒฌํด
|
| 403 |
+
|
| 404 |
+
[์ค์ ์์ฑ ์ง์นจ]
|
| 405 |
+
1. ์ ์ฒด ๊ธ์ ์ต์ 4000์ ์ด์์ผ๋ก ์์ฑํ์ธ์.
|
| 406 |
+
2. ๊ฐ ์์ฌ๋ ์ต์ 600์ ์ด์ ์์ฑํ๊ณ , ์๋ก ์ ๊ธฐ์ ์ผ๋ก ์ฐ๊ฒฐ๋๊ฒ ํ์ธ์.
|
| 407 |
+
3. ์ ๋ชฉ์ ๋ฐ๋ก ์ฌ์ฉํ์ง ๋ง๊ณ , ๋์
๋ถ, ์์ฌ, ๋ง๋ฌด๋ฆฌ๋ฅผ ํ๋์ ์ฐ๊ฒฐ๋ ๊ธ๋ก ์์ฑํ์ธ์.
|
| 408 |
+
4. ๊ธฐ์ ์ ์ ํ์ฑ์ ์ ์งํ๋ฉด์ ์ ํํ ํต์ฌ๊ธฐ๋ฅ์ ๋ํ ์ฌ์ธต์ ๋ถ์๊ณผ ๊ตฌ์ฒด์ ์ธ ์ ๋ณด๋ฅผ ์ ๊ณตํ์ธ์.
|
| 409 |
+
5. ๋ง์ผํ
์ ๊ณผ์ฅ ํํ๋ณด๋ค๋ ์ฌ์ค์ ์ด๊ณ ๋ถ์์ ์ธ ํํ์ ์ฌ์ฉํ์ธ์.
|
| 410 |
+
6. ๋ถํ์ํ ๋ฐ๋ณต์ด๋ ์ฅํฉํ ์ค๋ช
์ ํผํ๊ณ , ํต์ฌ ์ ๋ณด์ ํต์ฐฐ์ ๊ฐ์กฐํ์ธ์.
|
| 411 |
+
7. ์ ์ฒด ๊ธ์ ์ผ๊ด์ฑ์ ์ ์งํ๊ณ , ๋ฌธ๋จ ๊ฐ ์์ฐ์ค๋ฌ์ด ํ๋ฆ์ ๋ง๋์ธ์.
|
| 412 |
+
8. ์์ฌ๋ ํต์ฌ๊ธฐ๋ฅ์ ์ฑ๊ฒฉ์ ๋ง๊ฒ ๊ฐ์ฅ ์ ์ ํ ๊ฒ์ ์์ ๋กญ๊ฒ ์ ์ ํ์ธ์.
|
| 413 |
+
|
| 414 |
+
์ฐธ๊ณ ๊ธ:
|
| 415 |
+
{references[0]}
|
| 416 |
+
{references[1] if len(references) > 1 else ""}
|
| 417 |
+
{references[2] if len(references) > 2 else ""}
|
| 418 |
+
|
| 419 |
+
{style_prompt}
|
| 420 |
+
"""
|
| 421 |
+
|
| 422 |
+
# Gemini API ํธ์ถ
|
| 423 |
+
logging.info("ํต์ฌ๊ธฐ๋ฅ ์ง์คํ ๋ธ๋ก๊ทธ ๊ธ ์์ฑ ์์")
|
| 424 |
+
blog_content = call_gemini_api(blog_prompt, temperature=0.7)
|
| 425 |
+
logging.info(f"์์ฑ๋ ์๋ณธ ๊ธ ๊ธธ์ด: {len(blog_content)}")
|
| 426 |
+
|
| 427 |
+
# ํ์ฒ๋ฆฌ
|
| 428 |
+
processed_content = post_process_blog(blog_content, style)
|
| 429 |
+
|
| 430 |
+
# ๊ธ์ ์ ์ฒดํฌ
|
| 431 |
+
char_count = len(processed_content)
|
| 432 |
+
logging.info(f"์ฒ๋ฆฌ ํ ๋ธ๋ก๊ทธ ๊ธ ๊ธ์ ์: {char_count}")
|
| 433 |
+
|
| 434 |
+
# ๊ธ์ ์๊ฐ ๋ชฉํ์ ๋ฏธ๋ฌํ๋ฉด ํ์ฅ ์๋
|
| 435 |
+
if char_count < TARGET_CHAR_LENGTH:
|
| 436 |
+
logging.info(f"๊ธ์ ์ ๋ถ์กฑ ({char_count} < {TARGET_CHAR_LENGTH}), ํ์ฅ ์๋")
|
| 437 |
+
|
| 438 |
+
expansion_prompt = f"""
|
| 439 |
+
[ํต์ฌ๊ธฐ๋ฅ ๋ถ์ ํ์ฅ ์์ฒญ]
|
| 440 |
+
ํ์ฌ ๊ธ์ ๋ชฉํ ๊ธ์์์ธ 4000์์ ๋ฏธ์น์ง ๋ชปํฉ๋๋ค. ํ์ฌ ๊ธ์์๋ ์ฝ {char_count}์์
๋๋ค.
|
| 441 |
+
์ ํํ ํต์ฌ๊ธฐ๋ฅ: {selected_feature}
|
| 442 |
+
|
| 443 |
+
[ํ์ฅ ์ง์นจ]
|
| 444 |
+
1. ์๋ ๊ธ์ ๊ตฌ์กฐ(๋์
๋ถ, 5๊ฐ์ง ์์ฌ, ๋ง๋ฌด๋ฆฌ)๋ฅผ ์ ์งํ๋ฉด์ ๋ด์ฉ์ ํ์ฅํ์ธ์.
|
| 445 |
+
2. ๊ฐ ์์ฌ์ ๋ ๊ตฌ์ฒด์ ์ธ ์ ๋ณด, ์์, ๋ถ์ ๋ด์ฉ์ ์ถ๊ฐํ์ธ์.
|
| 446 |
+
3. ์์ ์ ํ๋ฆ์ ์ ์งํ๊ณ , ๋ถํ์ํ ๋งํฌ๋ค์ด ์ฌ์ฉ์ ํผํ์ธ์.
|
| 447 |
+
4. ๊ธ์ ์ ์ฒด ์ผ๊ด์ฑ๊ณผ ์์ง์ฑ์ ์ ์งํ์ธ์.
|
| 448 |
+
|
| 449 |
+
์๋ณธ ๊ธ:
|
| 450 |
+
{processed_content}
|
| 451 |
+
"""
|
| 452 |
+
|
| 453 |
+
# ํ์ฅ ์๋
|
| 454 |
+
expanded_content = call_gemini_api(expansion_prompt, temperature=0.75)
|
| 455 |
+
processed_content = post_process_blog(expanded_content, style)
|
| 456 |
+
|
| 457 |
+
# ๋ค์ ๊ธ์ ์ ์ฒดํฌ
|
| 458 |
+
char_count = len(processed_content)
|
| 459 |
+
logging.info(f"ํ์ฅ ํ ๋ธ๋ก๊ทธ ๊ธ ๊ธ์ ์: {char_count}")
|
| 460 |
+
|
| 461 |
+
# HTML ๋ณํ
|
| 462 |
+
final_html = convert_to_html(processed_content)
|
| 463 |
+
|
| 464 |
+
return final_html
|
| 465 |
+
|
| 466 |
+
except Exception as e:
|
| 467 |
+
logging.error(f"๋ธ๋ก๊ทธ ๊ธ ์์ฑ ์ค ์ค๋ฅ ๋ฐ์: {str(e)}")
|
| 468 |
+
return f"<p>๋ธ๋ก๊ทธ ๊ธ ์์ฑ ์ค ์ค๋ฅ ๋ฐ์: {str(e)}</p>"
|
| 469 |
+
|
| 470 |
+
def get_style_prompt(style="์น๊ทผํ"):
|
| 471 |
+
"""๋ธ๋ก๊ทธ ๊ธ์ ์คํ์ผ ํ๋กฌํํธ๋ฅผ ๋ฐํ"""
|
| 472 |
+
prompts = {
|
| 473 |
+
"์น๊ทผํ": """
|
| 474 |
+
[์น๊ทผํ ํต์ฌ๊ธฐ๋ฅ ๋ฆฌ๋ทฐ ์คํ์ผ ๊ฐ์ด๋]
|
| 475 |
+
1. ํค๊ณผ ์ด์กฐ
|
| 476 |
+
- ๋ํํ๋ฏ ํธ์ํ๊ณ ์น๊ทผํ ๋งํฌ ์ฌ์ฉ (์: "์ค๋์ ~์ ๋ํด ์์๋ณผ๊ฒ์")
|
| 477 |
+
- 1์ธ์นญ ์์ ์ผ๋ก ์ง์ ์ฌ์ฉํ ๊ฒฝํ์ ์์ํ๊ฒ ํํ
|
| 478 |
+
- ๊ตฌ์ด์ฒด์ ์ผ์์ ์ธ ํํ ์ฌ์ฉํ์ฌ ์น๊ทผํจ ์ ์ง
|
| 479 |
+
|
| 480 |
+
2. ๋ฌธ์ฅ ๋ฐ ์ดํฌ
|
| 481 |
+
- 'ํด์์ฒด'๋ก ์์ฑ (์: "~ํ์ด์", "~์ธ ๊ฒ ๊ฐ์์")
|
| 482 |
+
- ๋ฌธ์ฅ์ ๊ธธ์ง ์๊ฒ ์์ฐ์ค๋ฝ๊ฒ ์ฐ๊ฒฐ
|
| 483 |
+
- ๊ธฐ์ ์ ๋ด์ฉ๋ ์ฝ๊ณ ์ดํดํ๊ธฐ ํธํ ํํ์ผ๋ก ์ค๋ช
|
| 484 |
+
|
| 485 |
+
3. ์ ๋ณด ์ ๋ฌ ๋ฐฉ์
|
| 486 |
+
- ๊ฐ์ธ ๊ฒฝํ๊ณผ ์ฒด๊ฐ์ ์ค์ฌ์ผ๋ก ์ ๋ณด ์ ๋ฌ
|
| 487 |
+
- ์ ๋ฌธ์ ์ธ ๋ด์ฉ๋ ์ผ์์ ์ธ ๋น์ ์ ์์๋ก ํ์ด์ ์ค๋ช
|
| 488 |
+
- "์ ๊ฐ ์ฌ์ฉํด๋ณด๋~", "์ค์ ๋ก ๊ฒฝํํด๋ณด๋ฉด~"๊ณผ ๊ฐ์ ํํ ํ์ฉ
|
| 489 |
+
- ๋
์์๊ฒ ์ง์ ๋งํ๋ฏ ์ค๊ฐ์ค๊ฐ "~ํ์๋ฉด ์ข์์" ๊ฐ์ ์กฐ์ธ ์ถ๊ฐ
|
| 490 |
+
""",
|
| 491 |
+
"์ผ๋ฐ": """
|
| 492 |
+
[์ผ๋ฐ์ ์ธ ํต์ฌ๊ธฐ๋ฅ ๋ฆฌ๋ทฐ ์คํ์ผ ๊ฐ์ด๋]
|
| 493 |
+
1. ํค๊ณผ ์ด์กฐ
|
| 494 |
+
- ๊ฐ๊ด์ ์ด๊ณ ์ค๋ฆฝ์ ์ธ ํค ์ ์ง
|
| 495 |
+
- ์ง์ ์ ์ธ ๊ฒฝํ๊ณผ ๊ฐ๊ด์ ๋ฐ์ดํฐ๋ฅผ ๊ท ํ ์๊ฒ ํ์ฉ
|
| 496 |
+
- ์กด๋๋ง ์ฌ์ฉํ๋ ๋ฑ๋ฑํ์ง ์๊ฒ ํํ
|
| 497 |
+
|
| 498 |
+
2. ๋ฌธ์ฅ ๋ฐ ์ดํฌ
|
| 499 |
+
- 'ํฉ๋๋ค์ฒด' ์ฌ์ฉ (์: "~ํฉ๋๋ค", "~์
๋๋ค")
|
| 500 |
+
- ๋ช
ํํ๊ณ ๊ฐ๊ฒฐํ ๋ฌธ์ฅ ๊ตฌ์ฑ
|
| 501 |
+
- ๋ด์ฉ์ ๋
ผ๋ฆฌ์ ํ๋ฆ์ ์ค์
|
| 502 |
+
|
| 503 |
+
3. ์ ๋ณด ์ ๋ฌ ๋ฐฉ์
|
| 504 |
+
- ์ฌ์ค๊ณผ ๋ฐ์ดํฐ๋ฅผ ์ค์ฌ์ผ๋ก ๋ด์ฉ ์ ๊ฐ
|
| 505 |
+
- ๊ฐ์ธ ๊ฒฝํ๊ณผ ๊ฐ๊ด์ ๋ถ์์ ์ ์ ํ ํผํฉ
|
| 506 |
+
- ๋ถํ์ํ ๊ณผ์ฅ์ด๋ ์ฃผ๊ด์ ํ๊ฐ ์ต์ํ
|
| 507 |
+
- ์ค์ฉ์ ์ธ ๊ด์ ์์ ๊ธฐ๋ฅ์ ์ฅ๋จ์ ๊ท ํ์๊ฒ ์์
|
| 508 |
+
""",
|
| 509 |
+
"์ ๋ฌธ์ ์ธ": """
|
| 510 |
+
[์ ๋ฌธ์ ์ธ ํต์ฌ๊ธฐ๋ฅ ๋ฆฌ๋ทฐ ์คํ์ผ ๊ฐ์ด๋]
|
| 511 |
+
1. ํค๊ณผ ์ด์กฐ
|
| 512 |
+
- ์ ๋ฌธ์ ์ด๊ณ ๋ถ์์ ์ธ ํค ์ฌ์ฉ
|
| 513 |
+
- ๊ธฐ์ ์ ๊น์ด์ ์ ํ์ฑ ๊ฐ์กฐ
|
| 514 |
+
- ์กด์ค๊ณผ ๊ถ์๋ฅผ ๋๋ ์ ์๋ ํํ ์ฌ์ฉ
|
| 515 |
+
|
| 516 |
+
2. ๋ฌธ์ฅ ๋ฐ ์ดํฌ
|
| 517 |
+
- 'ํฉ๋๋ค์ฒด'๋ก ์ผ๊ด์ฑ ์๊ฒ ์์ฑ
|
| 518 |
+
- ๋
ผ๋ฆฌ์ ์ด๊ณ ์ฒด๊ณ์ ์ธ ๋ฌธ์ฅ ๊ตฌ์ฑ
|
| 519 |
+
- ์ ๋ฌธ ์ฉ์ด๋ฅผ ์ ์ ํ ํ์ฉํ๋ ํ์์ ๊ฐ๋ตํ ์ค๋ช
์ ๊ณต
|
| 520 |
+
|
| 521 |
+
3. ์ ๋ณด ์ ๋ฌ ๋ฐฉ์
|
| 522 |
+
- ๊ธฐ์ ์ ์๋ฆฌ์ ๋ฉ์ปค๋์ฆ์ ๋ํ ์ฌ์ธต ๋ถ์
|
| 523 |
+
- ๋ฒค์น๋งํฌ ๋ฐ์ดํฐ์ ๊ตฌ์ฒด์ ์์น๋ฅผ ํ์ฉํ ๊ฐ๊ด์ ํ๊ฐ
|
| 524 |
+
- ๊ฒฝ์ ์ ํ๊ณผ์ ์ธ๋ถ์ ์ธ ๊ธฐ์ ๋น๊ต ์ ๊ณต
|
| 525 |
+
- ๊ธฐ๋ฅ์ ๊ธฐ์ ์ ํ๊ณ์ ๋ฐ์ ๊ฐ๋ฅ์ฑ์ ๋ํ ํต์ฐฐ ์ ์
|
| 526 |
+
"""
|
| 527 |
+
}
|
| 528 |
+
return prompts.get(style, prompts["์น๊ทผํ"])
|
| 529 |
+
|
| 530 |
+
def call_gemini_api(prompt, temperature=TEMPERATURE, top_p=TOP_P):
|
| 531 |
+
"""Gemini API ํธ์ถ ํจ์"""
|
| 532 |
+
try:
|
| 533 |
+
logging.info("Gemini API ํธ์ถ ์์")
|
| 534 |
+
response = client.models.generate_content(
|
| 535 |
+
model="gemini-2.0-flash",
|
| 536 |
+
contents=[prompt],
|
| 537 |
+
config=types.GenerateContentConfig(
|
| 538 |
+
max_output_tokens=MAX_TOKENS,
|
| 539 |
+
temperature=temperature,
|
| 540 |
+
top_p=top_p
|
| 541 |
+
)
|
| 542 |
+
)
|
| 543 |
+
logging.info("Gemini API ํธ์ถ ์๋ฃ")
|
| 544 |
+
return response.text.strip()
|
| 545 |
+
except Exception as e:
|
| 546 |
+
logging.error(f"Gemini API ํธ์ถ ์ค ์ค๋ฅ ๋ฐ์: {str(e)}")
|
| 547 |
+
return f"API ํธ์ถ ์ค ์ค๋ฅ ๋ฐ์: {str(e)}"
|
| 548 |
+
|
| 549 |
+
# API ํจ์๋ค
|
| 550 |
+
def generate_outline_4(category, style, ref1, ref2, ref3):
|
| 551 |
+
features = generate_outline(category, style, ref1, ref2, ref3)
|
| 552 |
+
# 3๊ฐ์ ๋ฌธ์์ด ํํ ๋ฐํ
|
| 553 |
+
return (features[0], features[1], features[2])
|
| 554 |
+
|
| 555 |
+
def generate_blog_post_4(category, style, ref1, ref2, ref3, outline):
|
| 556 |
+
# outline์ ์ ํ๋ ํต์ฌ๊ธฐ๋ฅ ์ด๋ฆ
|
| 557 |
+
return generate_blog_post(category, style, ref1, ref2, ref3, outline)
|