4g3gf / visit_review_blog.py
ssboost's picture
Create visit_review_blog.py
2070c47 verified
import os
import gradio as gr
from bs4 import BeautifulSoup
from datetime import datetime
from zoneinfo import ZoneInfo
import tempfile
import requests
import re
import logging
from PIL import Image
from urllib.request import urlopen
import io
# google-genai ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž„ํฌํŠธ
from google import genai
# ๋กœ๊น… ์„ค์ •
logging.basicConfig(level=logging.WARNING)
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
# ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด Gemini API ํ‚ค๋ฅผ ๊ฐ€์ ธ์˜ด
API_KEY = os.getenv("GEMINI_API_KEY")
if API_KEY is None:
raise ValueError("GENAI_API_KEY ํ™˜๊ฒฝ ๋ณ€์ˆ˜๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.")
client = genai.Client(api_key=API_KEY)
# Gemini API๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ํ•จ์ˆ˜ (Gemini๋Š” max_tokens, temperature, top_p ํŒŒ๋ผ๋ฏธํ„ฐ ์—†์ด ํ”„๋กฌํ”„ํŠธ๋ฅผ ๊ฒฐํ•ฉํ•˜์—ฌ ์š”์ฒญ)
def call_api(content, system_message, max_tokens=None, temperature=None, top_p=None):
try:
prompt = system_message + "\n" + content
response = client.models.generate_content(
model="gemini-2.0-flash",
contents=prompt
)
return response.text.strip()
except Exception as e:
logger.error(f"API ํ˜ธ์ถœ ์˜ค๋ฅ˜: {str(e)}")
return f"Gemini API Error: {str(e)}"
def analyze_info(data):
return (f"์„ ํƒํ•œ ์นดํ…Œ๊ณ ๋ฆฌ: {data['category']}\n"
f"์„ ํƒํ•œ ํฌ์ŠคํŒ… ์Šคํƒ€์ผ: {data['style']}\n"
f"์ฐธ๊ณ  ๊ธ€1: {data['references1']}\n"
f"์ฐธ๊ณ  ๊ธ€2: {data['references2']}\n"
f"์ฐธ๊ณ  ๊ธ€3: {data['references3']}\n")
def generate_outline(category, style, references1, references2, references3, photo_recommendations):
data = {
'category': category,
'style': style,
'references1': references1,
'references2': references2,
'references3': references3,
'photo_recommendations': photo_recommendations
}
full_content = analyze_info(data)
logger.info(f"์•„์›ƒ๋ผ์ธ ์ƒ์„ฑ์„ ์œ„ํ•œ ์ „์ฒด ๋‚ด์šฉ: {full_content}")
system_prompt = get_outline_prompt(data['category']) + "\n\n" + get_style_prompt(data['style'])
user_prompt = f"{full_content}\n\n์‚ฌ์ง„ ํ‚ค์›Œ๋“œ: {photo_recommendations}"
modified_text = call_api(user_prompt, system_prompt, 2000, 0.7, 0.95)
# API ์˜ค๋ฅ˜ ํ™•์ธ
if modified_text is None or modified_text.startswith("Gemini API Error"):
logger.error(f"์•„์›ƒ๋ผ์ธ ์ƒ์„ฑ ์ค‘ API ์˜ค๋ฅ˜: {modified_text}")
raise Exception(f"์•„์›ƒ๋ผ์ธ ์ƒ์„ฑ API ์˜ค๋ฅ˜: {modified_text}")
# ๋ถˆํ•„์š”ํ•œ ๋นˆ ์ค„ ์ œ๊ฑฐ: ์—ฐ์†๋˜๋Š” ๊ฐœํ–‰ ๋ฌธ์ž๋ฅผ ๋‹จ์ผ ๊ฐœํ–‰์œผ๋กœ ๋ณ€๊ฒฝ
modified_text = re.sub(r'\n\s*\n', '\n', modified_text)
logger.info(f"Generated outline: {modified_text}")
return modified_text
def remove_unwanted_phrases(text):
unwanted_phrases = [
'์—ฌ๋Ÿฌ๋ถ„', '์ตœ๊ทผ', '๋งˆ์ง€๋ง‰์œผ๋กœ', '๊ฒฐ๋ก ์ ์œผ๋กœ', '๊ฒฐ๊ตญ',
'์ข…ํ•ฉ์ ์œผ๋กœ', '๋”ฐ๋ผ์„œ', '๋งˆ๋ฌด๋ฆฌ', '์š”์•ฝ'
]
words = re.findall(r'\S+|\n', text)
result_words = [word for word in words if not any(phrase in word for phrase in unwanted_phrases)]
return ' '.join(result_words).replace(' \n ', '\n').replace(' \n', '\n').replace('\n ', '\n')
def format_sentences(text):
"""
๊ธด ๋ฌธ์žฅ์„ 3~6๊ฐœ ๋‹จ์–ด ๋‹จ์œ„๋กœ ๋ถ„๋ฆฌํ•˜๋Š” ํ•จ์ˆ˜ (ํ•œ๊ตญ์–ด์— ์ตœ์ ํ™”)
"""
if text is None:
return "" # text๊ฐ€ None์ธ ๊ฒฝ์šฐ ๋นˆ ๋ฌธ์ž์—ด ๋ฐ˜ํ™˜
# ๋ฌธ์žฅ ๋‹จ์œ„๋กœ ๋ถ„๋ฆฌ
sentences = re.split(r'(?<=[.!?])\s+', text)
formatted_sentences = []
for sentence in sentences:
# ๋ฌธ์žฅ์ด ์ถฉ๋ถ„ํžˆ ๊ธธ ๊ฒฝ์šฐ๋งŒ ๋ถ„๋ฆฌ ์ฒ˜๋ฆฌ
if len(sentence) > 20: # ๋” ์งง์€ ๋ฌธ์žฅ์€ ๊ทธ๋Œ€๋กœ ์œ ์ง€
# ๋„์–ด์“ฐ๊ธฐ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋‹จ์–ด ๋ถ„๋ฆฌ
words = sentence.split()
if len(words) <= 4: # ์ด๋ฏธ 6๋‹จ์–ด ์ดํ•˜๋ฉด ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ
formatted_sentences.append(sentence)
continue
chunk = []
word_count = 0
for word in words:
chunk.append(word)
word_count += 1
# ํ•œ๊ธ€์€ ์˜์–ด๋ณด๋‹ค ํ•œ ๋‹จ์–ด๊ฐ€ ๋” ๊ธธ๊ธฐ ๋•Œ๋ฌธ์—, ๋‹จ์–ด ์ˆ˜๋ฅผ 4~7๊ฐœ๋กœ ์กฐ์ •
if word_count >= 4 and (word_count >= 7 or re.search(r'[,;:]$', word)):
formatted_sentences.append(' '.join(chunk))
chunk = []
word_count = 0
# ๋‚จ์€ ๋‹จ์–ด๋“ค ์ฒ˜๋ฆฌ
if chunk:
formatted_sentences.append(' '.join(chunk))
else:
formatted_sentences.append(sentence)
return "\n".join(formatted_sentences)
def extract_keywords(text, top_n=5):
from sklearn.feature_extraction.text import CountVectorizer
vectorizer = CountVectorizer(stop_words='english', ngram_range=(1,2))
count_matrix = vectorizer.fit_transform([text])
terms = vectorizer.get_feature_names_out()
counts = count_matrix.sum(axis=0).A1
term_counts = sorted(zip(terms, counts), key=lambda x: x[1], reverse=True)
return [term for term, count in term_counts[:top_n]]
def get_outline_prompt(category):
if category == "๋ฐฉ๋ฌธํ›„๊ธฐํ˜•":
return """
## ์‹œ์Šคํ…œ ์—ญํ• 
๋‹น์‹ ์€ ์ˆ˜๋…„๊ฐ„์˜ ๊ฒฝํ—˜์„ ๊ฐ€์ง„ ์ „๋ฌธ ๋ฐฉ๋ฌธ ๋ฆฌ๋ทฐ ๋ธ”๋กœ๊ฑฐ์ž…๋‹ˆ๋‹ค. ๋ง›์ง‘, ์นดํŽ˜, ์ˆ™์†Œ, ๊ด€๊ด‘์ง€ ๋“ฑ ๋‹ค์–‘ํ•œ ์žฅ์†Œ์— ๋Œ€ํ•œ ์ƒ์ƒํ•œ ๋ฆฌ๋ทฐ๋กœ ๋งŽ์€ ๋…์ž๋“ค์˜ ์‹ ๋ขฐ๋ฅผ ๋ฐ›๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
## ๋ถ„์„ ๋‹จ๊ณ„
1. ์ฐธ๊ณ ๊ธ€ 3๊ฐœ๋ฅผ ์ฒ ์ €ํžˆ ๋ถ„์„ํ•˜์—ฌ ํ•ต์‹ฌ ์ฃผ์ œ์™€ ์ค‘์š” ์ •๋ณด ํŒŒ์•…
2. ๋ฐฉ๋ฌธํ•œ ์žฅ์†Œ์˜ ์œ ํ˜•๊ณผ ํŠน์„ฑ ์‹๋ณ„ (์‹๋‹น, ์นดํŽ˜, ์ˆ™์†Œ, ๊ด€๊ด‘์ง€ ๋“ฑ)
3. ๋ฆฌ๋ทฐ์˜ ํ•ต์‹ฌ์ด ๋  5๊ฐ€์ง€ ์ฃผ์š” ์š”์†Œ ํŒŒ์•… (๋ถ„์œ„๊ธฐ, ๋ง›, ์„œ๋น„์Šค, ๊ฐ€๊ฒฉ, ํŠน๋ณ„ํ•จ ๋“ฑ)
## ์•„์›ƒ๋ผ์ธ ๊ตฌ์„ฑ ์›์น™
1. ๋„์ž…๋ถ€(1๊ฐœ) - ํ˜ธ๊ธฐ์‹ฌ์„ ์ž๊ทนํ•˜๋Š” ์ œ๋ชฉ์œผ๋กœ ์‹œ์ž‘
2. ๋ณธ๋ก (4-5๊ฐœ) - ์ฐธ๊ณ ๊ธ€ ๋ถ„์„์„ ํ†ตํ•ด ๋ฐœ๊ฒฌํ•œ ์žฅ์†Œ/๊ฒฝํ—˜์˜ ํ•ต์‹ฌ ๊ฐ€์น˜์™€ ํŠน์ง•์„ ๋‹ด์€ ์†Œ์ œ๋ชฉ
* ์ฐธ๊ณ ๊ธ€์—์„œ ๊ฐ€์žฅ ๊ฐ•์กฐ๋˜๋Š” ํŠน์ง•์ด๋‚˜ ์žฅ์ 
* ๋ฐฉ๋ฌธ์ž๋“ค์ด ๊ฐ€์žฅ ๊ด€์‹ฌ์„ ๊ฐ€์งˆ ๋งŒํ•œ ์š”์†Œ
* ์ฐจ๋ณ„ํ™”๋œ ๊ฒฝํ—˜์ด๋‚˜ ๋…ํŠนํ•œ ํŠน์„ฑ
* ์‹ค์šฉ์ ์ธ ์ •๋ณด๋‚˜ ์•Œ์•„๋‘๋ฉด ์ข‹์€ ํŒ
* (์œ„ ํ•ญ๋ชฉ๋“ค์€ ์˜ˆ์‹œ์ผ ๋ฟ, ์ฐธ๊ณ ๊ธ€ ๋ถ„์„์„ ํ†ตํ•ด ์ž์œ ๋กญ๊ฒŒ ๊ฒฐ์ •)
3. ๊ฒฐ๋ก (1๊ฐœ) - ์ „์ฒด ๊ฒฝํ—˜์„ ์š”์•ฝํ•˜๋Š” ๋งค๋ ฅ์ ์ธ ์ œ๋ชฉ
## ํ•ต์‹ฌ ์ง€์นจ
- **์™„์ „ํžˆ ํ•œ๊ตญ์–ด๋กœ๋งŒ ์ž‘์„ฑ**ํ•  ๊ฒƒ
- ์†Œ์ œ๋ชฉ์€ **์ตœ๋Œ€ 30์ž ์ด๋‚ด**๋กœ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ž‘์„ฑ
- ํ˜ธ๊ธฐ์‹ฌ์„ ์ž๊ทนํ•˜๋Š” ํ‘œํ˜„ ์‚ฌ์šฉ (์˜ˆ: "๊ผญ ์•Œ์•„์•ผ ํ• ", "๋†€๋ผ์šด", "์ˆจ๊ฒจ์ง„")
- ์žฅ์†Œ์˜ ๊ฐ€์žฅ ๋งค๋ ฅ์ ์ธ ํฌ์ธํŠธ๊ฐ€ ์†Œ์ œ๋ชฉ์— ๋ฐ˜์˜๋˜๋„๋ก ๊ตฌ์„ฑ
- **์‚ฌ์ง„ ํ‚ค์›Œ๋“œ๋Š” ์†Œ์ œ๋ชฉ ๊ฒฐ์ •์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์Œ** (๋ณธ๋ฌธ ์ž‘์„ฑ ์‹œ ์ฐธ๊ณ ์‚ฌํ•ญ์œผ๋กœ๋งŒ ํ™œ์šฉ)
- ์ „์ฒด ์•„์›ƒ๋ผ์ธ์€ ๋„์ž…๋ถ€(1) + ๋ณธ๋ก (์ตœ๋Œ€ 5๊ฐœ) + ๊ฒฐ๋ก (1)์œผ๋กœ ๊ตฌ์„ฑ
## ์ถœ๋ ฅ ํ˜•์‹
* ์ฐธ๊ณ ๊ธ€ ๋ถ„์„์„ ํ†ตํ•ด ๊ฐ€์žฅ ํ•ต์‹ฌ์ ์ธ ์ฃผ์ œ์™€ ํŠน์ง•์„ ํŒŒ์•…ํ•˜์—ฌ ์ž์œ ๋กญ๊ฒŒ ์•„์›ƒ๋ผ์ธ ๊ตฌ์„ฑ
* ํ•˜์ง€๋งŒ ๋ฐ˜๋“œ์‹œ ๋‹ค์Œ ๊ตฌ์กฐ๋ฅผ ์œ ์ง€ํ•  ๊ฒƒ:(๊ฐ ํ•ญ๋ชฉ๋‹น 1๋ฒˆ์—”ํ„ฐ๋ฅผ ์ ์šฉํ•˜์š” ๋นˆ์นธ์ด ๋‚˜์˜ค์ง€ ์•Š๋„๋กํ•˜๋ผ.)
- ๋„์ž…๋ถ€: 1๊ฐœ (ํ˜ธ๊ธฐ์‹ฌ์„ ์ž๊ทนํ•˜๋Š” ํฅ๋ฏธ๋กœ์šด ์ œ๋ชฉ)
- ๋ณธ๋ก : 4-5๊ฐœ (์žฅ์†Œ/๊ฒฝํ—˜์˜ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ํŠน์ง•์„ ๋ฐ˜์˜ํ•œ ์ œ๋ชฉ)
- ๊ฒฐ๋ก : 1๊ฐœ (์ „์ฒด ๊ฒฝํ—˜ ์š”์•ฝ ์ œ๋ชฉ)
* ์†Œ์ œ๋ชฉ์€ ์žฅ์†Œ์˜ ์‹ค์ œ ๊ฒฝํ—˜๊ณผ ํŠน์ง•์— ๋งž๊ฒŒ ์ž์œ ๋กญ๊ฒŒ ๊ตฌ์„ฑ
* ์‚ฌ์ง„ ํ‚ค์›Œ๋“œ์— ๋งž์ถ”์ง€ ๋ง๊ณ , ์ฐธ๊ณ ๊ธ€ ๋ถ„์„์„ ํ†ตํ•ด ๋ฐœ๊ฒฌํ•œ ํ•ต์‹ฌ ๊ฐ€์น˜์™€ ํŠน์ง• ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌ์„ฑ
์˜ˆ์‹œ ํ˜•์‹ (์ฐธ๊ณ ์šฉ์ผ ๋ฟ, ๋‚ด์šฉ์€ ์ฐธ๊ณ ๊ธ€์— ๋”ฐ๋ผ ์™„์ „ํžˆ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์Œ):
๋„์ž…๋ถ€: [ํฅ๋ฏธ๋กœ์šด ๋„์ž… ์ œ๋ชฉ]
๋ณธ๋ก 1: [ํ•ต์‹ฌ ํŠน์ง•/์žฅ์  ๊ด€๋ จ ์ œ๋ชฉ]
๋ณธ๋ก 2: [๋˜ ๋‹ค๋ฅธ ์ฃผ์š” ํŠน์ง• ๊ด€๋ จ ์ œ๋ชฉ]
๋ณธ๋ก 3: [์ฐจ๋ณ„ํ™” ์š”์†Œ ๊ด€๋ จ ์ œ๋ชฉ]
๋ณธ๋ก 4: [์œ ์šฉํ•œ ์ •๋ณด/ํŒ ๊ด€๋ จ ์ œ๋ชฉ]
๋ณธ๋ก 5: [์ถ”๊ฐ€ ํŠน์ง•/์ •๋ณด ๊ด€๋ จ ์ œ๋ชฉ] (ํ•„์š”์‹œ)
๊ฒฐ๋ก : [์ „์ฒด ๊ฒฝํ—˜ ์š”์•ฝ ์ œ๋ชฉ]
"""
def get_blog_post_prompt(category):
if category == "๋ฐฉ๋ฌธํ›„๊ธฐํ˜•":
return """
# ๋ฐฉ๋ฌธํ›„๊ธฐํ˜• ๋ธ”๋กœ๊ทธ ์ฝ˜ํ…์ธ  ์ƒ์„ฑ ์‹œ์Šคํ…œ [v2.0]
## ์‹œ์Šคํ…œ ์—ญํ• 
๋‹น์‹ ์€ ์ˆ˜๋งŒ ๋ช…์˜ ํŒ”๋กœ์›Œ๋ฅผ ๋ณด์œ ํ•œ ์ธ๊ธฐ ๋ฐฉ๋ฌธ ๋ฆฌ๋ทฐ ๋ธ”๋กœ๊ฑฐ์ž…๋‹ˆ๋‹ค. ์ƒ์ƒํ•œ ํ˜„์žฅ๊ฐ๊ณผ ๋””ํ…Œ์ผํ•œ ์ •๋ณด ์ œ๊ณต์œผ๋กœ ๋…์ž๋“ค์—๊ฒŒ ์‹ค์ œ ๋ฐฉ๋ฌธํ•œ ๋“ฏํ•œ ๊ฒฝํ—˜์„ ์ „๋‹ฌํ•˜๋Š” ์ „๋ฌธ๊ฐ€์ž…๋‹ˆ๋‹ค.
## ์ฝ˜ํ…์ธ  ์ƒ์„ฑ ์›์น™
### 1. ๊ธ€์˜ ๊ตฌ์กฐ
- **๋„์ž…๋ถ€** (์ „์ฒด ๊ธ€์˜ 10-15%):
* ์žฅ์†Œ ์†Œ๊ฐœ ๋ฐ ๋ฐฉ๋ฌธ ๊ณ„๊ธฐ
* ์ฒซ์ธ์ƒ๊ณผ ๊ธฐ๋Œ€๊ฐ ํ‘œํ˜„
* ์œ„์น˜์ •๋ณด์™€ ํ•จ๊ป˜ "[์ง€๋„ ์ •๋ณด๋ฅผ ๋„ฃ์–ด์ฃผ์„ธ์š”]" ๋ช…์‹œ
* ๊ธธ์ด: 500์ž ์ด์ƒ
- **๋ณธ๋ก ** (์ „์ฒด ๊ธ€์˜ 70-80%):
* ์•„์›ƒ๋ผ์ธ์˜ ๊ฐ ์†Œ์ œ๋ชฉ์— ๋งž์ถ˜ ์ƒ์„ธ ๋‚ด์šฉ
* ์žฅ์†Œ์˜ ๋ถ„์œ„๊ธฐ, ์ œํ’ˆ/์„œ๋น„์Šค ํ’ˆ์งˆ, ๊ฐ€๊ฒฉ, ์„œ๋น„์Šค ๋“ฑ ํ•ต์‹ฌ ์š”์†Œ ์ƒ์„ธ ์„ค๋ช…
* ์‹ค์ œ ๊ฒฝํ—˜ ๊ธฐ๋ฐ˜์˜ ์ƒ์ƒํ•œ ํ‘œํ˜„
* ๊ฐ ์„น์…˜์€ 400-600์ž ์ˆ˜์ค€์œผ๋กœ ๊ท ํ˜•์žˆ๊ฒŒ ์ž‘์„ฑ
* ๊ธธ์ด: 2500์ž ์ด์ƒ
- **๊ฒฐ๋ก ** (์ „์ฒด ๊ธ€์˜ 10-15%):
* ์ „์ฒด ๊ฒฝํ—˜ ์š”์•ฝ ๋ฐ ์ถ”์ฒœ ์ด์œ 
* ์ถ”๊ฐ€ ํŒ์ด๋‚˜ ๋ฐฉ๋ฌธ ์‹œ ์ฐธ๊ณ ์‚ฌํ•ญ
* ๊ธธ์ด: 400์ž ์ด์ƒ
### 2. ์‚ฌ์ง„ ์‚ฝ์ž… ์ง€์นจ
- ์‚ฌ์ง„ ํ‚ค์›Œ๋“œ๋Š” **๋‚ด์šฉ์— ๋งž๊ฒŒ** ๋ณธ๋ฌธ ์ค‘๊ฐ„์— ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์‚ฝ์ž…
- ์‚ฌ์ง„ ํ‚ค์›Œ๋“œ๋Š” ๋‚ด์šฉ๊ณผ ๊ด€๋ จ ์žˆ์„ ๋•Œ๋งŒ ์‚ฌ์šฉํ•˜๊ณ , ์–ต์ง€๋กœ ๋ชจ๋“  ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ
- ์‚ฌ์ง„ ํ‚ค์›Œ๋“œ๋Š” ๋Œ€๊ด„ํ˜ธ๋กœ ํ‘œ์‹œ: [ํ‚ค์›Œ๋“œ]
- ์‚ฌ์ง„ ํ‚ค์›Œ๋“œ ์•ž๋’ค๋กœ ๋นˆ ์ค„ ์‚ฝ์ž…
- ์‚ฌ์ง„ ํ‚ค์›Œ๋“œ๋Š” ์†Œ์ œ๋ชฉ์ด๋‚˜ ๋‚ด์šฉ ๊ตฌ์„ฑ์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์œผ๋ฉฐ, ๊ธ€์˜ ์ž์—ฐ์Šค๋Ÿฌ์šด ํ๋ฆ„์„ ๋”ฐ๋ผ ์ ์ ˆํ•œ ์œ„์น˜์—๋งŒ ์‚ฝ์ž…
- ๊ธ€์˜ ๋‚ด์šฉ๊ณผ ๋งž์ง€ ์•Š๋Š” ์‚ฌ์ง„ ํ‚ค์›Œ๋“œ๋Š” ๊ณผ๊ฐํžˆ ์ƒ๋žต
- ์‚ฌ์ง„ ํ‚ค์›Œ๋“œ๊ฐ€ ์—†๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ๊ธ€์˜ ํ€„๋ฆฌํ‹ฐ๋‚˜ ์™„์„ฑ๋„์—๋Š” ์ „ํ˜€ ์˜ํ–ฅ ์—†์Œ
### 3. ๊ธ€์“ฐ๊ธฐ ์Šคํƒ€์ผ
- ํ•œ ๋ฌธ์žฅ์„ 2-3 ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋ˆ ์„œ ์ค„๋ฐ”๊ฟˆํ•˜์—ฌ ๊ฐ€๋…์„ฑ ํ–ฅ์ƒ
- ์†Œ์ œ๋ชฉ์€ ๋ณผ๋“œ์ฒด๋กœ ๊ตฌ๋ถ„ํ•˜๊ณ  ์ „ํ›„์— ๋นˆ ์ค„ ์‚ฝ์ž…
- ๊ฐ๊ด€์  ์‚ฌ์‹ค๊ณผ ์ฃผ๊ด€์  ๊ฒฝํ—˜์„ ๊ท ํ˜•์žˆ๊ฒŒ ํ˜ผํ•ฉ
- ํ•ต์‹ฌ ์žฅ์ ๊ณผ ๋‹จ์ ์„ ์†”์งํ•˜๊ฒŒ ํ‘œํ˜„
- ๊ณผ์žฅ๋œ ํ‘œํ˜„๋ณด๋‹ค ๊ตฌ์ฒด์ ์ธ ๋””ํ…Œ์ผ๋กœ ์‹ ๋ขฐ๊ฐ ํ˜•์„ฑ
- ๊ฐ ๋ฌธ๋‹จ ์‚ฌ์ด์— ์ ์ ˆํ•œ ๋นˆ ์ค„์„ ์‚ฝ์ž…ํ•˜์—ฌ ๊ฐ€๋…์„ฑ ๋†’์ž„
- ๊ธด ๋ฌธ๋‹จ์€ 2-3๊ฐœ์˜ ์ž‘์€ ๋ฌธ๋‹จ์œผ๋กœ ๋‚˜๋ˆ„์–ด ์ฝ๊ธฐ ํŽธํ•˜๊ฒŒ ๊ตฌ์„ฑ
### 4. ์ฝ˜ํ…์ธ  ํ’ˆ์งˆ ๊ธฐ์ค€
- ์‹ค์ œ ๊ฒฝํ—˜ํ•œ ๋“ฏํ•œ ๋””ํ…Œ์ผํ•œ ๋ฌ˜์‚ฌ
- ๋ชจ๋“  ๊ฐ๊ฐ(์‹œ๊ฐ, ์ฒญ๊ฐ, ๋ฏธ๊ฐ, ํ›„๊ฐ, ์ด‰๊ฐ)์„ ํ™œ์šฉํ•œ ํ‘œํ˜„
- ๊ฐ€๊ฒฉ, ์˜์—…์‹œ๊ฐ„, ํŠน๋ณ„ ํ˜œํƒ ๋“ฑ ์‹ค์šฉ์  ์ •๋ณด ํฌํ•จ
- ํŠน๋ณ„ํ•œ ํŒ์ด๋‚˜ ์•Œ๋ฉด ์œ ์šฉํ•œ ์ •๋ณด ์ œ๊ณต
- ์ „์ฒด ๊ธธ์ด: ์ตœ์†Œ 3000์ž์ž์ด์ƒ
### 5.์ถœ๋ ฅ ํ˜•์‹ ์š”๊ตฌ์‚ฌํ•ญ
- ์†Œ์ œ๋ชฉ์€ ๋ณผ๋“œ์ฒด๋กœ ํ‘œ์‹œํ•˜๊ณ  ์ „ํ›„์— ๋นˆ ์ค„ ์‚ฝ์ž…
- ๋ชจ๋“  ํ…์ŠคํŠธ๋Š” ๊ฐ€์šด๋ฐ ์ •๋ ฌ
- ๋ฌธ์žฅ์€ 2-3๊ฐœ ๋‹จ์œ„๋กœ ์ค„๋ฐ”๊ฟˆํ•˜์—ฌ ๊ฐ€๋…์„ฑ ํ™•๋ณด
- ๊ฐ ๋ฌธ๋‹จ ์‚ฌ์ด์—๋Š” ๋ฐ˜๋“œ์‹œ ๋นˆ ์ค„ ์‚ฝ์ž…
- ์‚ฌ์ง„ ํ‚ค์›Œ๋“œ๋Š” ํ•„์š”ํ•œ ์œ„์น˜์—๋งŒ ๋Œ€๊ด„ํ˜ธ๋กœ ํ‘œ์‹œํ•˜๊ณ  ์ „ํ›„์— ๋นˆ ์ค„ ์‚ฝ์ž…
- ๋ชจ๋“  ๋‹จ๋ฝ์€ ์ ์ ˆํ•œ ๊ธธ์ด๋กœ ๊ท ํ˜•์žˆ๊ฒŒ ๊ตฌ์„ฑ
- ํŠนํžˆ ์ค‘์š”ํ•œ ๋‚ด์šฉ์ด๋‚˜ ๊ฐ•์กฐํ•˜๊ณ  ์‹ถ์€ ๋ถ€๋ถ„์€ ๋ฌธ์žฅ ๋‹จ์œ„๋กœ ์ค„๋ฐ”๊ฟˆํ•˜์—ฌ ์‹œ๊ฐ์  ์ž„ํŒฉํŠธ ๊ฐ•ํ™”
- ์ฐธ๊ณ ๊ธ€์˜ ๋‚ด์šฉ์„ ํ† ๋Œ€๋กœ ์ƒˆ๋กญ๊ฒŒ ๊ตฌ์„ฑํ•˜๋˜, ๋‹ค์Œ์„ ๋ฐ˜๋“œ์‹œ ์ค€์ˆ˜ํ•˜๋ผ:
- ์ฐธ๊ณ ๊ธ€์— ์–ธ๊ธ‰๋œ ๋‹‰๋„ค์ž„, ์ด๋ฆ„, ํšŒ์‚ฌ๋ช…, ๋ธŒ๋žœ๋“œ๋ช… ๋“ฑ์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜์ง€ ๋ง๊ณ  ๋‹ค๋ฅธ ๋ช…์นญ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋ผ.
- ์ฟ ํŒกํŒŒํŠธ๋„ˆ์Šค, ๊ด‘๊ณ , ์ œํ’ˆ ํ˜‘์ฐฌ, ์†Œ์ •์˜ ๊ธˆ์•ก์ด๋‚˜ ์‚ฌ์€ํ’ˆ์„ ๋ฐ›์•˜๋‹ค๋Š” ๋‚ด์šฉ ์ œ์™ธํ•  ๊ฒƒ
- ์ฐธ๊ณ ๊ธ€ ์ž‘์„ฑ์ž์˜ ๊ฒฝํ—˜์ด ์•„๋‹Œ ๋‚˜์˜ ์ง์ ‘ ๊ฒฝํ—˜์œผ๋กœ ์žฌ๊ตฌ์„ฑํ•  ๊ฒƒ
"""
def get_style_prompt(style):
prompts = {
"์นœ๊ทผํ•œ": """
# ์นœ๊ทผํ•œ ๋ธ”๋กœ๊ทธ ๊ธ€์“ฐ๊ธฐ ์Šคํƒ€์ผ ํ”„๋กœํ•„
## ํ†ค & ๋ณด์ด์Šค
- ๋…์ž์™€ ๋Œ€ํ™”ํ•˜๋Š” ๋“ฏํ•œ ์นœ๊ทผํ•˜๊ณ  ํŽธ์•ˆํ•œ ์–ดํˆฌ
- '~ํ•ด์š”', '~๋„ค์š”', '~์ธ ๊ฒƒ ๊ฐ™์•„์š”' ๋“ฑ ๊ตฌ์–ด์ฒด ํ‘œํ˜„ ์ ๊ทน ํ™œ์šฉ
- ๊ฐ์ •๊ณผ ๋А๋‚Œ์„ ์†”์งํ•˜๊ฒŒ ํ‘œํ˜„ํ•˜๋Š” ๊ฐœ์ธ์ ์ธ ์–ด์กฐ
- ๊ฐํƒ„์‚ฌ๋ฅผ ์ ์ ˆํžˆ ํ™œ์šฉ (์˜ˆ: ์™€~, ์ •๋ง!, ใ…Žใ…Ž)
- ์ด๋ชจํ‹ฐ์ฝ˜์€ ์‚ฌ์šฉํ•˜์ง€๋งˆ๋ผ
## ๋ฌธ์ฒด & ๋ฌธ๋ฒ•
- **ํ•ด์š”์ฒด ์ „์šฉ**: ๋ชจ๋“  ๋ฌธ์žฅ์€ '~ํ•ฉ๋‹ˆ๋‹ค'๊ฐ€ ์•„๋‹Œ '~ํ•ด์š”'๋กœ ์ข…๊ฒฐ
- ์งง๊ณ  ๊ฐ„๊ฒฐํ•œ ๋ฌธ์žฅ ๊ตฌ์กฐ๋กœ ์ฝ๊ธฐ ์‰ฝ๊ฒŒ ๊ตฌ์„ฑ
- ์งˆ๋ฌธํ˜• ๋ฌธ์žฅ์œผ๋กœ ๋…์ž์˜ ๊ณต๊ฐ ์œ ๋„ (์˜ˆ: "์—ฌ๋Ÿฌ๋ถ„๋„ ๊ทธ๋ ‡์ง€ ์•Š๋‚˜์š”?")
- ๊ฐœ์ธ์  ๊ฒฝํ—˜์„ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๊ณต์œ ํ•˜๋Š” 1์ธ์นญ ์‹œ์ 
## ์–ดํœ˜ & ํ‘œํ˜„
- ์ผ์ƒ์ ์ด๊ณ  ์‰ฌ์šด ๋‹จ์–ด ์„ ํƒ (์ „๋ฌธ์šฉ์–ด ์‚ฌ์šฉ ์‹œ ํ’€์–ด์„œ ์„ค๋ช…)
- ์ง๊ด€์ ์ธ ๋น„์œ ์™€ ์˜ˆ์‹œ๋กœ ์„ค๋ช… (์˜ˆ: "๋งˆ์น˜ ๊ตฌ๋ฆ„ ์œ„๋ฅผ ๊ฑท๋Š” ๋“ฏํ•œ ๋А๋‚Œ์ด์—ˆ์–ด์š”")
- ์ƒ์ƒํ•œ ๊ฐ๊ฐ์  ํ‘œํ˜„์œผ๋กœ ํ˜„์žฅ๊ฐ ์ „๋‹ฌ
- ๊ณผ์žฅ๋œ ํ‘œํ˜„๋ณด๋‹ค๋Š” ์†”์งํ•œ ๋А๋‚Œ ์ค‘์‹ฌ์˜ ์„œ์ˆ 
## ๋…์ž์™€์˜ ๊ด€๊ณ„
- ๋…์ž๋ฅผ '์—ฌ๋Ÿฌ๋ถ„'์œผ๋กœ ์ง€์นญํ•˜๋ฉฐ ์นœ๊ทผ๊ฐ ํ˜•์„ฑ
- ๋…์ž์˜ ์ž…์žฅ์„ ๊ณ ๋ คํ•œ ๊ณต๊ฐ๋Œ€ ํ˜•์„ฑ ํ‘œํ˜„ ์‚ฌ์šฉ
- ๋…์ž์—๊ฒŒ ์ง์ ‘ ๋ง์„ ๊ฑฐ๋Š” ๋“ฏํ•œ ๋Œ€ํ™”ํ˜• ๋ฌธ์ฒด
- ์ •๋ณด ์ „๋‹ฌ๊ณผ ํ•จ๊ป˜ ๊ฐœ์ธ์ ์ธ ํŒ์ด๋‚˜ ์กฐ์–ธ ์ œ๊ณต
## ์˜ˆ์‹œ ๋ฌธ์žฅ
"์—ฌ๊ธฐ ๋ถ„์œ„๊ธฐ๊ฐ€ ์ •๋ง ์ข‹๋”๋ผ๊ณ ์š”.
์€์€ํ•œ ์กฐ๋ช…๊ณผ ์ฐจ๋ถ„ํ•œ ์Œ์•…์ด
๋งˆ์Œ์„ ํŽธ์•ˆํ•˜๊ฒŒ ํ•ด์คฌ์–ด์š”.
๊ฐ€๊ฒฉ์€ ์กฐ๊ธˆ ์žˆ๋Š” ํŽธ์ด์ง€๋งŒ
๊ทธ๋งŒํผ ๊ฐ€์น˜ ์žˆ๋Š” ๊ฒฝํ—˜์ด์—ˆ๋‹ต๋‹ˆ๋‹ค.
๋‹ค์Œ์— ๋ฐฉ๋ฌธํ•˜์‹ค ๋•Œ๋Š”
ํ‰์ผ ์˜คํ›„๊ฐ€ ํ•œ์ ํ•ด์„œ ์ถ”์ฒœํ•ด์š”!"
""",
"์ผ๋ฐ˜": """
# ๊ท ํ˜• ์žกํžŒ ๋ธ”๋กœ๊ทธ ๊ธ€์“ฐ๊ธฐ ์Šคํƒ€์ผ ํ”„๋กœํ•„
## ํ†ค & ๋ณด์ด์Šค
- ๊ฐ๊ด€์  ์ •๋ณด์™€ ์ฃผ๊ด€์  ์˜๊ฒฌ์ด ๊ท ํ˜•์„ ์ด๋ฃฌ ์ค‘๋ฆฝ์  ์–ด์กฐ
- ์ •์ค‘ํ•˜๊ณ  ์˜ˆ์˜ ๋ฐ”๋ฅธ ์–ดํˆฌ๋กœ ์‹ ๋ขฐ๊ฐ ํ˜•์„ฑ
- ๊ณผ์žฅ๋œ ํ‘œํ˜„์ด๋‚˜ ๊ฐ์ • ํ‘œํ˜„ ์ž์ œ
- ๋ช…ํ™•ํ•˜๊ณ  ๊ฐ„๊ฒฐํ•œ ๋ฌธ์žฅ์œผ๋กœ ํ•ต์‹ฌ ์ •๋ณด ์ „๋‹ฌ
## ๋ฌธ์ฒด & ๋ฌธ๋ฒ•
- 'ํ•ฉ๋‹ˆ๋‹ค/์Šต๋‹ˆ๋‹ค' ์ข…๊ฒฐ์–ด๋ฏธ ์‚ฌ์šฉ์œผ๋กœ ๋‹จ์ •ํ•œ ์ธ์ƒ
- ๋…ผ๋ฆฌ์  ๊ตฌ์กฐ์™€ ๋ช…ํ™•ํ•œ ํ๋ฆ„์„ ๊ฐ€์ง„ ๋ฌธ์žฅ ๊ตฌ์„ฑ
- ๋ฌธ๋ฒ•์ ์œผ๋กœ ์˜ฌ๋ฐ”๋ฅด๊ณ  ์ •์ œ๋œ ํ‘œํ˜„ ์‚ฌ์šฉ
- ์ ์ ˆํ•œ ๊ธธ์ด์˜ ๋‹จ๋ฝ์œผ๋กœ ๊ฐ€๋…์„ฑ ํ™•๋ณด
## ์–ดํœ˜ & ํ‘œํ˜„
- ์ผ๋ฐ˜ ๋…์ž๊ฐ€ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” ์ˆ˜์ค€์˜ ์–ดํœ˜ ์„ ํƒ
- ์ „๋ฌธ ์šฉ์–ด ์‚ฌ์šฉ ์‹œ ๊ฐ„๋žตํ•œ ์„ค๋ช… ์ œ๊ณต
- ๊ตฌ์ฒด์ ์ธ ์ˆ˜์น˜์™€ ์‚ฌ์‹ค ์ค‘์‹ฌ์˜ ์„ค๋ช…
- ๋น„๊ต์™€ ๋Œ€์กฐ๋ฅผ ํ†ตํ•œ ๋ช…ํ™•ํ•œ ์ •๋ณด ์ „๋‹ฌ
## ๋…์ž์™€์˜ ๊ด€๊ณ„
- ์ ์ ˆํ•œ ๊ฑฐ๋ฆฌ๊ฐ ์œ ์ง€๋กœ ์‹ ๋ขฐ์„ฑ ํ™•๋ณด
- ๋…์ž๋ฅผ ์œ„ํ•œ ์œ ์šฉํ•œ ์ •๋ณด ์ค‘์‹ฌ ๊ตฌ์„ฑ
- ์ง์ ‘์ ์ธ ์ถ”์ฒœ์ด๋‚˜ ์˜๊ฒฌ ์ œ์‹œ ์‹œ ๊ทผ๊ฑฐ ํ•จ๊ป˜ ์ œ๊ณต
- ๋…์ž๊ฐ€ ์Šค์Šค๋กœ ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ๊ด€์  ์ •๋ณด ์ œ๊ณต
## ์˜ˆ์‹œ ๋ฌธ์žฅ
"์ด ๋ ˆ์Šคํ† ๋ž‘์€ 2020๋…„์— ์˜คํ”ˆํ•œ
๋ชจ๋˜ ์ดํƒˆ๋ฆฌ์•ˆ ๋‹ค์ด๋‹์ž…๋‹ˆ๋‹ค.
๋‚ด๋ถ€๋Š” 50์„ ๊ทœ๋ชจ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์œผ๋ฉฐ
ํ”„๋ผ์ด๋น—ํ•œ ๊ณต๊ฐ„๋„ ๋งˆ๋ จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
๊ฐ€๊ฒฉ๋Œ€๋Š” 1์ธ๋‹น 3๋งŒ์›์—์„œ 5๋งŒ์› ์„ ์œผ๋กœ
๋‹ค๋ฅธ ์ดํƒˆ๋ฆฌ์•ˆ ๋ ˆ์Šคํ† ๋ž‘๊ณผ ๋น„๊ตํ–ˆ์„ ๋•Œ
์ค‘์ƒ์œ„๊ถŒ์— ์†ํ•ฉ๋‹ˆ๋‹ค.
ํŠนํžˆ ์ž์ฒด ์ œ์ž‘ํ•˜๋Š” ํŒŒ์Šคํƒ€ ๋ฉด์ด
์ด ๊ณณ์˜ ์ฐจ๋ณ„์ ์ž…๋‹ˆ๋‹ค."
""",
"์ „๋ฌธ์ ์ธ": """
# ์ „๋ฌธ๊ฐ€ํ˜• ๋ธ”๋กœ๊ทธ ๊ธ€์“ฐ๊ธฐ ์Šคํƒ€์ผ ํ”„๋กœํ•„
## ํ†ค & ๋ณด์ด์Šค
- ๊นŠ์ด ์žˆ๋Š” ์ง€์‹๊ณผ ๊ฒฝํ—˜์ด ๋А๊ปด์ง€๋Š” ์ „๋ฌธ์  ์–ด์กฐ
- ๊ฐ๊ด€์  ์‚ฌ์‹ค๊ณผ ๋ถ„์„์  ๊ด€์ ์ด ๋‹๋ณด์ด๋Š” ๋…ผ๋ฆฌ์  ์„œ์ˆ 
- ๊ถŒ์œ„ ์žˆ๊ณ  ์„ค๋“๋ ฅ ์žˆ๋Š” ์–ดํˆฌ๋กœ ์‹ ๋ขฐ๊ฐ ํ˜•์„ฑ
- ์ •์ œ๋œ ํ‘œํ˜„๊ณผ ์ฒด๊ณ„์ ์ธ ๊ตฌ์„ฑ์œผ๋กœ ์ „๋ฌธ์„ฑ ๊ฐ•์กฐ
## ๋ฌธ์ฒด & ๋ฌธ๋ฒ•
- ์ •ํ™•ํ•˜๊ณ  ๊ฐ„๊ฒฐํ•œ ๋ฌธ์žฅ ๊ตฌ์กฐ
- ๋ณต์žกํ•œ ๊ฐœ๋…๋„ ๋ช…ํ™•ํžˆ ์ „๋‹ฌํ•˜๋Š” ๋…ผ๋ฆฌ์  ํ๋ฆ„
- ์ „๋ฌธ ์šฉ์–ด์˜ ์ ์ ˆํ•œ ํ™œ์šฉ๊ณผ ์„ค๋ช…
- ํ•™์ˆ ์  ๊ธ€์“ฐ๊ธฐ์— ๊ฐ€๊นŒ์šด ์ฒด๊ณ„์  ๋ฌธ๋‹จ ๊ตฌ์„ฑ
## ์–ดํœ˜ & ํ‘œํ˜„
- ํ•ด๋‹น ๋ถ„์•ผ์˜ ์ „๋ฌธ ์šฉ์–ด์™€ ๊ฐœ๋… ์ ๊ทน ํ™œ์šฉ
- ๊ตฌ์ฒด์ ์ธ ์ˆ˜์น˜์™€ ๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜ ์„ค๋ช…
- ๋น„๊ต ๋ถ„์„๊ณผ ํ‰๊ฐ€๋ฅผ ์œ„ํ•œ ์ „๋ฌธ์  ๊ธฐ์ค€ ์ œ์‹œ
- ์ •ํ™•ํ•œ ์ธ์šฉ๊ณผ ์ฐธ์กฐ๋ฅผ ํ†ตํ•œ ์‹ ๋ขฐ์„ฑ ํ™•๋ณด
## ๋…์ž์™€์˜ ๊ด€๊ณ„
- ์ „๋ฌธ๊ฐ€๋กœ์„œ ์ง€์‹๊ณผ ํ†ต์ฐฐ๋ ฅ ๊ณต์œ 
- ๊ฐ๊ด€์  ํ‰๊ฐ€์™€ ์ „๋ฌธ์  ์กฐ์–ธ ์ œ๊ณต
- ๋…์ž์˜ ์ง€์  ํ˜ธ๊ธฐ์‹ฌ์„ ์ž๊ทนํ•˜๋Š” ์‹ฌ์ธต ๋ถ„์„
- ์—…๊ณ„ ํŠธ๋ Œ๋“œ๋‚˜ ์ „๋ฌธ์  ๊ด€์ ์—์„œ์˜ ํ‰๊ฐ€ ์ œ์‹œ
## ์˜ˆ์‹œ ๋ฌธ์žฅ
"๋ณธ ๋ ˆ์Šคํ† ๋ž‘์€ ๋ฏธ์‰๋ฆฐ ์ถœ์‹  ์…ฐํ”„๊ฐ€
์ดํƒˆ๋ฆฌ์•ˆ ํ€ด์ง„์˜ ์ •์ˆ˜๋ฅผ ์„ ๋ณด์ด๋Š” ๊ณต๊ฐ„์ž…๋‹ˆ๋‹ค.
ํŠนํžˆ 72์‹œ๊ฐ„ ์ €์˜จ ์ˆ™์„ฑํ•œ ๋„์šฐ๋ฅผ
ํ™”๋•์—์„œ 90์ดˆ๊ฐ„ ๊ตฌ์›Œ๋‚ด๋Š” ๋‚˜ํด๋ฆฌ ๋ฐฉ์‹์˜ ํ”ผ์ž๋Š”
๊ตญ๋‚ด ์ตœ๊ณ  ์ˆ˜์ค€์œผ๋กœ ํ‰๊ฐ€๋ฐ›๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์‹์žฌ๋ฃŒ๋Š” 100% ์œ ๊ธฐ๋† ์ธ์ฆ์„ ๋ฐ›์€
์ง€์—ญ ๋†๊ฐ€์—์„œ ์ง์†ก๋˜๋ฉฐ,
์™€์ธ ํŽ˜์–ด๋ง์„ ์œ„ํ•œ ์†Œ๋ฏˆ๋ฆฌ์—์˜ ์ „๋ฌธ์ ์ธ ํ๋ ˆ์ด์…˜์ด
์‹์‚ฌ ๊ฒฝํ—˜์„ ํ•œ์ธต ๋” ํ’๋ถ€ํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค."
"""
}
return prompts.get(style, "ํฌ์ŠคํŒ… ์Šคํƒ€์ผ ํ”„๋กฌํ”„ํŠธ")
def generate_blog_post(category, style, references1, references2, references3, outline, photo_recommendations):
try:
logger.info("1. ๋ฐ์ดํ„ฐ ์ค€๋น„")
data = {
'category': category,
'style': style,
'references1': references1,
'references2': references2,
'references3': references3,
'outline': outline,
'photo_recommendations': photo_recommendations
}
logger.info("2. ํ”„๋กฌํ”„ํŠธ ์ค€๋น„")
system_prompt = get_blog_post_prompt(data['category'])
style_prompt = get_style_prompt(data['style'])
# ์ˆ˜์ •๋œ ์œ ์ € ํ”„๋กฌํ”„ํŠธ - ๊ฐ ์ค„๋‹น 4~7๋‹จ์–ด ์ง€์ •
user_prompt = f"""
**๋ฐ˜๋“œ์‹œ 3000์ž ์ด์ƒ ์ž‘์„ฑํ•˜๋ผ**
์ฐธ๊ณ ๊ธ€1: {data['references1']}
์ฐธ๊ณ ๊ธ€2: {data['references2']}
์ฐธ๊ณ ๊ธ€3: {data['references3']}
์•„์›ƒ๋ผ์ธ: {data['outline']}
์‚ฌ์ง„ ํ‚ค์›Œ๋“œ: {data['photo_recommendations']}
๊ธ€ ์ž‘์„ฑ ํ˜•์‹ ๊ทœ์น™:
1. ๊ฐ ๋ฌธ์žฅ์€ 4~7๋‹จ์–ด ๋‹จ์œ„๋กœ ์ค„๋ฐ”๊ฟˆํ•˜์—ฌ ์ž‘์„ฑํ•  ๊ฒƒ
2. ์‚ฌ์ง„ ํ‚ค์›Œ๋“œ๋Š” [ํ‚ค์›Œ๋“œ] ํ˜•ํƒœ๋กœ ์•ž๋’ค์— ๋นˆ ์ค„์„ ์ถ”๊ฐ€ํ•  ๊ฒƒ
3. ์†Œ์ œ๋ชฉ์€ ๋ณผ๋“œ์ฒด๋กœ ํ‘œ์‹œํ•˜๊ณ  ์ „ํ›„์— ๋นˆ ์ค„ ์‚ฝ์ž…ํ•  ๊ฒƒ
4. ๋ชจ๋“  ํ…์ŠคํŠธ๋Š” ๊ฐ€์šด๋ฐ ์ •๋ ฌ๋กœ ์ž‘์„ฑํ•  ๊ฒƒ
5. ๋ฌธ๋‹จ ์‚ฌ์ด์—๋Š” ๋ฐ˜๋“œ์‹œ ๋นˆ ์ค„์„ ๋„ฃ์„ ๊ฒƒ
"""
logger.info("3. ๊ธ€ ์ƒ์„ฑ ์‹œ์ž‘")
full_post = call_api(
user_prompt,
system_prompt + "\n" + style_prompt,
max_tokens=15000,
temperature=0.7,
top_p=0.95
)
# API ํ˜ธ์ถœ ์‘๋‹ต ํ™•์ธ
if full_post is None or full_post.startswith("Gemini API Error"):
error_msg = "API ์‘๋‹ต ์—†์Œ" if full_post is None else full_post
logger.error(f"๋ธ”๋กœ๊ทธ ๊ธ€ ์ƒ์„ฑ API ์˜ค๋ฅ˜: {error_msg}")
return f"<p style='color: red;'>๊ธ€ ์ƒ์„ฑ ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค: {error_msg}</p>"
logger.info(f"Gemini๊ฐ€ ์ƒ์„ฑํ•œ ์›๋ณธ ๊ธ€ ๊ธธ์ด: {len(full_post)}")
logger.info("4. ๋ถˆํ•„์š”ํ•œ ๋ฌธ๊ตฌ ์ œ๊ฑฐ ๋ฐ ํ…์ŠคํŠธ ํ˜•์‹ ์กฐ์ •")
# ๋ถˆํ•„์š”ํ•œ ๋ฌธ๊ตฌ ์ œ๊ฑฐ
filtered_post = remove_unwanted_phrases(full_post).lstrip()
# ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋ฌธ์žฅ์„ 4~7๋‹จ์–ด ๋‹จ์œ„๋กœ ์ถ”๊ฐ€ ํฌ๋งทํŒ…
formatted_post = format_sentences(filtered_post)
# ์‚ฌ์ง„ ํ‚ค์›Œ๋“œ ํŒจํ„ด ์•ž๋’ค๋กœ ๋นˆ ์ค„ ์ถ”๊ฐ€
pattern = r'(\[[\w\s๊ฐ€-ํžฃ]+\])'
processed_text = re.sub(pattern, r'\n\n\1\n\n', formatted_post)
# ์ค‘๋ณต๋œ ๋นˆ ์ค„ ์ •๋ฆฌ
processed_text = re.sub(r'\n{3,}', '\n\n', processed_text)
logger.info("5. HTML ๋ณ€ํ™˜")
html_post = convert_to_html(processed_text)
logger.info("6. ์ตœ์ข… ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜")
return html_post
except Exception as e:
logger.error(f"๊ธ€ ์ƒ์„ฑ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {str(e)}")
return f"<p style='color: red;'>๊ธ€ ์ƒ์„ฑ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {str(e)}</p>"
def convert_to_html(text):
if text is None:
return "<p>ํ…์ŠคํŠธ ๋ณ€ํ™˜ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.</p>"
lines = text.split('\n')
html_lines = []
in_paragraph = False
for i, line in enumerate(lines):
line = line.strip()
# ๋นˆ ์ค„ ์ฒ˜๋ฆฌ
if not line:
if in_paragraph:
html_lines.append("</p>")
in_paragraph = False
html_lines.append("<br>")
continue
# ์‚ฌ์ง„ ํ‚ค์›Œ๋“œ ์ฒ˜๋ฆฌ (๋Œ€๊ด„ํ˜ธ๋กœ ๋œ ํ…์ŠคํŠธ)
if re.match(r'^\[[\w\s๊ฐ€-ํžฃ]+\]$', line):
if in_paragraph:
html_lines.append("</p>")
in_paragraph = False
html_lines.append("<br>")
html_lines.append(f"<p style='text-align: center; font-weight: bold; color: #0066cc; margin: 15px 0; font-size: 1.1em;'>{line}</p>")
html_lines.append("<br>")
continue
# ํ—ค๋” ์ฒ˜๋ฆฌ
if line.startswith('####'):
if in_paragraph:
html_lines.append("</p>")
in_paragraph = False
html_lines.append(f"<h4 style='text-align: center; margin: 20px 0;'>{line[4:].strip()}</h4>")
elif line.startswith('###'):
if in_paragraph:
html_lines.append("</p>")
in_paragraph = False
html_lines.append(f"<h3 style='text-align: center; margin: 20px 0;'>{line[3:].strip()}</h3>")
elif line.startswith('##'):
if in_paragraph:
html_lines.append("</p>")
in_paragraph = False
html_lines.append(f"<h2 style='text-align: center; margin: 25px 0; color: #2c3e50;'>{line[2:].strip()}</h2>")
elif line.startswith('#'):
if in_paragraph:
html_lines.append("</p>")
in_paragraph = False
html_lines.append(f"<h1 style='text-align: center; margin: 30px 0; color: #2c3e50;'>{line[1:].strip()}</h1>")
# ๋ฆฌ์ŠคํŠธ ์•„์ดํ…œ ์ฒ˜๋ฆฌ
elif line.startswith('- '):
if in_paragraph:
html_lines.append("</p>")
in_paragraph = False
html_lines.append(f"<li style='text-align: center; list-style: none; margin: 5px 0;'>{line[2:]}</li>")
# ์ผ๋ฐ˜ ํ…์ŠคํŠธ ์ฒ˜๋ฆฌ - ๋‹จ๋ฝ ํ˜•์‹ ์œ ์ง€
else:
# ๋ณผ๋“œ์ฒด ์ฒ˜๋ฆฌ
line = re.sub(r'\*\*(.*?)\*\*', r'<strong>\1</strong>', line)
# ์†Œ์ œ๋ชฉ ์ฒ˜๋ฆฌ (๋ณผ๋“œ์ฒด๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ฒฝ์šฐ)
if line.startswith('<strong>') and line.endswith('</strong>'):
if in_paragraph:
html_lines.append("</p>")
in_paragraph = False
html_lines.append(f"<h3 style='text-align: center; margin: 20px 0; color: #34495e;'>{line}</h3>")
else:
# ์ผ๋ฐ˜ ํ…์ŠคํŠธ๋Š” ๋‹จ๋ฝ์œผ๋กœ ์ฒ˜๋ฆฌ
if not in_paragraph:
html_lines.append("<p style='text-align: center; margin: 8px 0; line-height: 1.8;'>")
in_paragraph = True
html_lines.append(f"{line}<br>")
# ๋งˆ์ง€๋ง‰ ๋‹จ๋ฝ ๋‹ซ๊ธฐ
if in_paragraph:
html_lines.append("</p>")
html_content = f"""
<div style="font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 800px; margin: 0 auto; padding: 20px;">
{"".join(html_lines)}
</div>
"""
return html_content
# API ํ•จ์ˆ˜๋“ค
def generate_outline_5(category, style, ref1, ref2, ref3, photo_recommendations):
return generate_outline(category, style, ref1, ref2, ref3, photo_recommendations)
def generate_blog_post_5(category, style, ref1, ref2, ref3, outline, photo_recommendations):
return generate_blog_post(category, style, ref1, ref2, ref3, outline, photo_recommendations)