|
import html |
|
import gradio as gr |
|
import requests |
|
from bs4 import BeautifulSoup |
|
from requests.adapters import HTTPAdapter |
|
from requests.packages.urllib3.util.retry import Retry |
|
import re |
|
import time |
|
import random |
|
import os |
|
from huggingface_hub import InferenceClient |
|
from fpdf import FPDF |
|
from transformers import pipeline |
|
import torch |
|
from diffusers import StableDiffusionXLPipeline |
|
import uuid |
|
import json |
|
from gradio_client import Client |
|
from urllib.parse import urljoin |
|
import requests |
|
from pexels_api import API |
|
import logging |
|
|
|
|
|
logging.basicConfig(level=logging.INFO) |
|
logger = logging.getLogger(__name__) |
|
|
|
import tiktoken |
|
|
|
def count_tokens(text): |
|
encoding = tiktoken.get_encoding("cl100k_base") |
|
return len(encoding.encode(text)) |
|
|
|
def truncate_text(text, max_tokens): |
|
encoding = tiktoken.get_encoding("cl100k_base") |
|
encoded = encoding.encode(text) |
|
if len(encoded) > max_tokens: |
|
return encoding.decode(encoded[:max_tokens]) |
|
return text |
|
|
|
def setup_session(): |
|
try: |
|
session = requests.Session() |
|
retries = Retry(total=5, backoff_factor=1, status_forcelist=[502, 503, 504]) |
|
session.mount('https://', HTTPAdapter(max_retries=retries)) |
|
return session |
|
except Exception as e: |
|
return None |
|
|
|
def generate_naver_search_url(query): |
|
base_url = "https://search.naver.com/search.naver?" |
|
params = {"ssc": "tab.blog.all", "sm": "tab_jum", "query": query} |
|
url = base_url + "&".join(f"{key}={value}" for key, value in params.items()) |
|
return url |
|
|
|
def crawl_blog_content(url, session): |
|
try: |
|
headers = { |
|
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3", |
|
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", |
|
"Accept-Language": "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7", |
|
"Accept-Encoding": "gzip, deflate, br", |
|
"Connection": "keep-alive", |
|
"Referer": "https://search.naver.com/search.naver", |
|
} |
|
|
|
|
|
delay = random.uniform(1, 2) |
|
time.sleep(delay) |
|
|
|
response = session.get(url, headers=headers) |
|
if response.status_code != 200: |
|
return "" |
|
|
|
soup = BeautifulSoup(response.content, "html.parser") |
|
content = soup.find("div", attrs={'class': 'se-main-container'}) |
|
|
|
if content: |
|
return clean_text(content.get_text()) |
|
else: |
|
return "" |
|
except Exception as e: |
|
return "" |
|
|
|
def crawl_naver_search_results(url, session): |
|
try: |
|
headers = { |
|
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3", |
|
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", |
|
"Accept-Language": "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7", |
|
"Accept-Encoding": "gzip, deflate, br", |
|
"Connection": "keep-alive", |
|
"Referer": "https://search.naver.com/search.naver", |
|
} |
|
response = session.get(url, headers=headers) |
|
if response.status_code != 200: |
|
return [] |
|
|
|
soup = BeautifulSoup(response.content, "html.parser") |
|
results = [] |
|
count = 0 |
|
for li in soup.find_all("li", class_=re.compile("bx.*")): |
|
if count >= 10: |
|
break |
|
for div in li.find_all("div", class_="detail_box"): |
|
for div2 in div.find_all("div", class_="title_area"): |
|
title = div2.text.strip() |
|
for a in div2.find_all("a", href=True): |
|
link = a["href"] |
|
if "blog.naver" in link: |
|
link = link.replace("https://", "https://m.") |
|
results.append({"์ ๋ชฉ": title, "๋งํฌ": link}) |
|
count += 1 |
|
if count >= 10: |
|
break |
|
if count >= 10: |
|
break |
|
if count >= 10: |
|
break |
|
|
|
return results |
|
except Exception as e: |
|
return [] |
|
|
|
def clean_text(text): |
|
text = re.sub(r'\s+', ' ', text).strip() |
|
return text |
|
|
|
def create_client(model_name): |
|
return InferenceClient(model_name, token=os.getenv("HF_TOKEN")) |
|
|
|
client = create_client("CohereForAI/c4ai-command-r-plus-08-2024") |
|
|
|
def call_api(content, system_message, max_tokens, temperature, top_p, max_retries=3): |
|
for attempt in range(max_retries): |
|
try: |
|
messages = [{"role": "system", "content": system_message}, {"role": "user", "content": content}] |
|
total_tokens = count_tokens(system_message) + count_tokens(content) + max_tokens |
|
if total_tokens > 32000: |
|
max_tokens = 32000 - count_tokens(system_message) - count_tokens(content) - 100 |
|
|
|
random_seed = random.randint(0, 1000000) |
|
response = client.chat_completion(messages=messages, max_tokens=max_tokens, temperature=temperature, top_p=top_p, seed=random_seed) |
|
modified_text = response.choices[0].message.content |
|
input_tokens = response.usage.prompt_tokens |
|
output_tokens = response.usage.completion_tokens |
|
total_tokens = response.usage.total_tokens |
|
return modified_text, input_tokens, output_tokens, total_tokens |
|
except HfHubHTTPError as e: |
|
if attempt < max_retries - 1: |
|
time.sleep(5) |
|
else: |
|
return f"API ํธ์ถ ์คํจ: {str(e)}", 0, 0, 0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def analyze_info(category, style, topic, references1, references2, references3): |
|
return f"์ ํํ ์นดํ
๊ณ ๋ฆฌ: {category}\n์ ํํ ํฌ์คํ
์คํ์ผ: {style}\n๋ธ๋ก๊ทธ ์ฃผ์ : {topic}\n์ฐธ๊ณ ๊ธ1: {references1}\n์ฐธ๊ณ ๊ธ2: {references2}\n์ฐธ๊ณ ๊ธ3: {references3}" |
|
|
|
def suggest_title(category, style, topic, references1, references2, references3): |
|
full_content = analyze_info(category, style, topic, references1, references2, references3) |
|
category_prompt = get_title_prompt(category) |
|
style_prompt = get_style_prompt(style) |
|
max_tokens = 5000 |
|
temperature = 0.8 |
|
top_p = 0.95 |
|
combined_prompt = f"{category_prompt}\n\n{style_prompt}\n\n์ถ๊ฐ ์ง์์ฌํญ: ์ ๋๋ก ์ ๋ชฉ์ '๋ธ๋ก๊ทธ'๋ '์ ๋ชฉ'์ด๋ผ๋ ๋จ์ด๋ฅผ ํฌํจํ์ง ๋ง์ธ์. ๊ฐ ์ ์์ ์ค์ ํฌ์คํธ ์ ๋ชฉ์ผ๋ก ๋ฐ๋ก ์ฌ์ฉํ ์ ์์ด์ผ ํฉ๋๋ค." |
|
modified_text, input_tokens, output_tokens, total_tokens = call_api(full_content, combined_prompt, max_tokens, temperature, top_p) |
|
|
|
|
|
titles = [line.strip() for line in modified_text.split('\n') if line.strip()] |
|
titles = [re.sub(r'^\d+\.\s*', '', title) for title in titles] |
|
|
|
|
|
titles = [title for title in titles if "๋ธ๋ก๊ทธ" not in title and "์ ๋ชฉ" not in title] |
|
|
|
token_usage_message = f"[์
๋ ฅ ํ ํฐ์: {input_tokens}]\n[์ถ๋ ฅ ํ ํฐ์: {output_tokens}]\n[์ด ํ ํฐ์: {total_tokens}]" |
|
return "\n".join(titles), token_usage_message |
|
|
|
|
|
|
|
def process_all_titles(category, style, topic): |
|
|
|
title_suggestions, _ = suggest_title(category, style, topic, "", "", "") |
|
titles = title_suggestions.split('\n') |
|
|
|
results = [] |
|
for title in titles[:10]: |
|
try: |
|
|
|
_, _, _, _, _, blog_content, _ = fetch_references_and_generate_all_steps(category, style, topic, title) |
|
|
|
if blog_content.startswith("API ํธ์ถ ์คํจ"): |
|
results.append(f"์ ๋ชฉ: {title}\n์์ฑ ์คํจ: {blog_content}\n\n") |
|
continue |
|
|
|
|
|
send_result = send_to_blogger(title, blog_content) |
|
|
|
results.append(f"์ ๋ชฉ: {title}\n์ ์ก ๊ฒฐ๊ณผ: {send_result}\n\n") |
|
except Exception as e: |
|
results.append(f"์ ๋ชฉ: {title}\n์ฒ๋ฆฌ ์ค ์ค๋ฅ ๋ฐ์: {str(e)}\n\n") |
|
|
|
time.sleep(5) |
|
|
|
return "\n".join(results) |
|
|
|
|
|
|
|
|
|
|
|
|
|
def fetch_references(topic, max_tokens=3000): |
|
search_url = generate_naver_search_url(topic) |
|
session = setup_session() |
|
if session is None: |
|
return "Failed to set up session.", "", "", "" |
|
results = crawl_naver_search_results(search_url, session) |
|
if not results: |
|
return "No results found.", "", "", "" |
|
|
|
selected_results = random.sample(results, 3) |
|
references1_content = truncate_text(f"์ ๋ชฉ: {selected_results[0]['์ ๋ชฉ']}\n๋ด์ฉ: {crawl_blog_content(selected_results[0]['๋งํฌ'], session)}", max_tokens) |
|
references2_content = truncate_text(f"์ ๋ชฉ: {selected_results[1]['์ ๋ชฉ']}\n๋ด์ฉ: {crawl_blog_content(selected_results[1]['๋งํฌ'], session)}", max_tokens) |
|
references3_content = truncate_text(f"์ ๋ชฉ: {selected_results[2]['์ ๋ชฉ']}\n๋ด์ฉ: {crawl_blog_content(selected_results[2]['๋งํฌ'], session)}", max_tokens) |
|
|
|
return "์ฐธ๊ณ ๊ธ ์์ฑ ์๋ฃ", references1_content, references2_content, references3_content |
|
|
|
|
|
|
|
def generate_outline(category, style, topic, references1, references2, references3, title, max_tokens=2000): |
|
full_content = analyze_info(category, style, topic, references1, references2, references3) |
|
content = truncate_text(f"{full_content}\nTitle: {title}", max_tokens) |
|
category_prompt = get_outline_prompt(category) |
|
style_prompt = get_style_prompt(style) |
|
combined_prompt = f"{category_prompt}\n\n{style_prompt}" |
|
modified_text, input_tokens, output_tokens, total_tokens = call_api(content, combined_prompt, 6000, 0.8, 0.95) |
|
token_usage_message = f"[์
๋ ฅ ํ ํฐ์: {input_tokens}]\n[์ถ๋ ฅ ํ ํฐ์: {output_tokens}]\n[์ด ํ ํฐ์: {total_tokens}]" |
|
return modified_text, token_usage_message |
|
|
|
def generate_blog_post(category, style, topic, references1, references2, references3, title, outline, max_tokens=4000): |
|
full_content = analyze_info(category, style, topic, references1, references2, references3) |
|
content = truncate_text(f"{full_content}\nTitle: {title}\nOutline: {outline}", max_tokens) |
|
category_prompt = get_blog_post_prompt(category) |
|
style_prompt = get_style_prompt(style) |
|
combined_prompt = f"{category_prompt}\n\n{style_prompt}" |
|
modified_text, input_tokens, output_tokens, total_tokens = call_api(content, combined_prompt, 8000, 0.8, 0.95) |
|
formatted_text = modified_text.replace('\n', '\n\n') |
|
token_usage_message = f"[์
๋ ฅ ํ ํฐ์: {input_tokens}]\n[์ถ๋ ฅ ํ ํฐ์: {output_tokens}]\n[์ด ํ ํฐ์: {total_tokens}]" |
|
return formatted_text, token_usage_message |
|
|
|
def fetch_references_and_generate_all_steps(category, style, topic, blog_title): |
|
_, references1_content, references2_content, references3_content = fetch_references(topic) |
|
|
|
outline_result, outline_token_usage = generate_outline(category, style, topic, references1_content, references2_content, references3_content, blog_title) |
|
|
|
blog_post_result, blog_post_token_usage = generate_blog_post(category, style, topic, references1_content, references2_content, references3_content, blog_title, outline_result) |
|
|
|
return references1_content, references2_content, references3_content, outline_result, outline_token_usage, blog_post_result, blog_post_token_usage |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_title_prompt(category): |
|
if (category == "์ผ๋ฐ"): |
|
return """ |
|
# ๋ธ๋ก๊ทธ ์ ๋ชฉ ์์ฑ ๊ท์น(์ผ๋ฐ) |
|
##[๊ธฐ๋ณธ๊ท์น] |
|
1. ๋ฐ๋์ ํ๊ตญ์ด(ํ๊ธ)๋ก ์์ฑํ๋ผ. |
|
2. ๋๋ ๊ฐ์ฅ ์ฃผ๋ชฉ๋ฐ๋ ๋ง์ผํฐ์ด๋ฉฐ ๋ธ๋ก๊ทธ ๋ง์ผํ
์ ๋ฌธ๊ฐ์ด๋ค. |
|
3. ํนํ ๋๋ '์ ๋ณด์ฑ(Informative)' ์ ๋ฌธ ๋ธ๋ก๊ทธ ๋ง์ผํ
์ ๋ฌธ๊ฐ์ด๋ค. |
|
4. ์ ๋ณด ์ ๊ณต์ ์ด์ ์ ๋ง์ถ์ด ์์ฑํ๋ค. |
|
##[๋ธ๋ก๊ทธ ์ ๋ชฉ ์์ฑ ๊ท์น] |
|
1. ๋ธ๋ก๊ทธ ์ ๋ชฉ 10๊ฐ๋ฅผ ์์ฑํ๊ณ ์ ๋ชฉ 10๊ฐ๋ง ์ถ๋ ฅํ๋ผ. |
|
2. ์ ๋ชฉ์ 40์ ์ด๋ด๋ก ์์ฑํ๋ผ. |
|
3. ์ ๊ณต๋ ์ฐธ๊ณ ๊ธ์ ๋ง์ถฐ ๋ธ๋ก๊ทธ ์ ๋ชฉ 10๊ฐ๋ฅผ ์์ฑํ๋ผ. |
|
4. ๋ฐ๋์ ํต์ฌํค์๋(Topic)๊ฐ ๋ฌธ์ฅ ์์ชฝ์ ๋ค์ด๊ฐ๋๋ก ์์ฑํ๋ผ. |
|
5. ํต์ฌ ํค์๋์ ์ฐ๊ด์ฑ ๋์ ์ฃผ์ ๋ฅผ ํฌํจํ์ฌ ์์ฑํ๋ผ. |
|
""" |
|
elif (category == "๊ฑด๊ฐ์ ๋ณด"): |
|
return """ |
|
# ๋ธ๋ก๊ทธ ์ ๋ชฉ ์์ฑ ๊ท์น(๊ฑด๊ฐ์ ๋ณด) |
|
##[๊ธฐ๋ณธ๊ท์น] |
|
1. ๋ฐ๋์ ํ๊ตญ์ด(ํ๊ธ)๋ก ์์ฑํ๋ผ. |
|
2. ๋๋ ๊ฐ์ฅ ์ฃผ๋ชฉ๋ฐ๋ ๋ง์ผํฐ์ด๋ฉฐ ๋ธ๋ก๊ทธ ๋ง์ผํ
์ ๋ฌธ๊ฐ์ด๋ค. |
|
3. ํนํ ๋๋ '๊ฑด๊ฐ, ์ํ ์ ๋ณด' ์ ๋ฌธ ๋ธ๋ก๊ทธ ๋ง์ผํฐ์ด๋ค. |
|
4. ์ ํํ๊ณ ์ ๋ฌธ์ ์ธ ์ ๋ณด ์ ๊ณต์ ์ด์ ์ ๋ง์ถ์ด ์์ฑํ๋ค. |
|
##[๋ธ๋ก๊ทธ ์ ๋ชฉ ์์ฑ ๊ท์น] |
|
1. ๋ธ๋ก๊ทธ ์ ๋ชฉ 10๊ฐ๋ฅผ ์์ฑํ๊ณ ์ ๋ชฉ 10๊ฐ๋ง ์ถ๋ ฅํ๋ผ. |
|
2. ์ ๋ชฉ์ 40์ ์ด๋ด๋ก ์์ฑํ๋ผ. |
|
3. ์ ๊ณต๋ ์ฐธ๊ณ ๊ธ์ ๋ง์ถฐ ๋ธ๋ก๊ทธ ์ ๋ชฉ 10๊ฐ๋ฅผ ์์ฑํ๋ผ. |
|
4. ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ๋ธ๋ก๊ทธ ์ฃผ์ , ํต์ฌํค์๋(Topic)๊ฐ ๋ฌธ์ฅ ์์ชฝ์ ๋ค์ด๊ฐ๋๋ก ์ ๋ชฉ์ ์์ฑํ๋ผ. |
|
5. ์ฐธ๊ณ ๊ธ์ ๋ถ์ํ์ฌ ๋
์๋ค์ด ๊ฑด๊ฐํ ์ํ์ ์ ์งํ๋ ๋ฐ ํ์ํ ์ ๋ณด๋ฅผ ๋ฐ์ํ๋ผ. |
|
""" |
|
|
|
def get_outline_prompt(category): |
|
if (category == "์ผ๋ฐ"): |
|
return """ |
|
# ๋ธ๋ก๊ทธ ์์ฃผ์ (Subtopic) ์์ฑ ๊ท์น(์ผ๋ฐ) |
|
##[๊ธฐ๋ณธ๊ท์น] |
|
1. ๋ฐ๋์ ํ๊ตญ์ด(ํ๊ธ)๋ก ์์ฑํ๋ผ. |
|
2. ๋๋ ๊ฐ์ฅ ์ฃผ๋ชฉ๋ฐ๋ ๋ง์ผํฐ์ด๋ฉฐ ๋ธ๋ก๊ทธ ๋ง์ผํ
์ ๋ฌธ๊ฐ์ด๋ค. |
|
3. ํนํ ๋๋ '์ ๋ณด์ฑ(Informative)' ์ ๋ฌธ ๋ธ๋ก๊ทธ ๋ง์ผํ
์ ๋ฌธ๊ฐ์ด๋ค. |
|
4. ์ ๋ณด ์ ๊ณต์ ์ด์ ์ ๋ง์ถ์ด ์์ฑํ๋ค. |
|
##[์์ฃผ์ ์์ฑ๊ท์น] |
|
1. [๊ธฐ๋ณธ๊ท์น]์ ๊ธฐ๋ณธ ์ ์ฉํ๋ผ. |
|
2. ๋ธ๋ก๊ทธ ๊ธ์ ์์ฑํ๊ธฐ ์ํ ์์ฃผ์ ๋ฅผ ์์ฑํ๋ผ. |
|
3. ์ ๊ณต๋ ์ฐธ๊ณ ๊ธ๊ณผ ๋ธ๋ก๊ทธ ์ฃผ์ , ์ ๋ชฉ์ ๋ฐํ์ผ๋ก ํต์ฌ ์ฃผ์ ๋ฅผ ํ์
ํ์ฌ ์์ฃผ์ ๋ฅผ ์์ฑํ๋ผ. |
|
4. ์ ์ฒด ๋งฅ๋ฝ์ ๋ง๊ฒ ์์ฃผ์ ๋ฅผ ์์ฑํ๋ผ. |
|
5. ์์ ๋ชฉ์ผ๋ก ์ฌ์ฉํ ์ ์๋๋ก 20์ ๋ด์ธ๋ก ์์ฑํ๋ผ. |
|
6. ๋
์๊ฐ ์ป๊ณ ์ ํ๋ ์ ๋ณด์ ํฅ๋ฏธ๋ก์ด ์ ๋ณด๋ฅผ ์ ๊ณตํ๋๋ก ์์ฃผ์ ๋ฅผ ์์ฑํ๋ผ. |
|
7. ์์ฃผ์ ์ ๋ณธ๋ก ์ ๋ด์ฉ์ด ์ถฉ๋ถํ ์์ฑ๋ ์ ์๋ ์์ฃผ์ ๋ก ์ค์ ํ๋ผ. |
|
8. ๋ฐ๋์ [์์ฃผ์ ๊ตฌ์ฑ]์ ๋ง๊ฒ ์ถ๋ ฅํ๋ผ. |
|
##[์์ฃผ์ ๊ตฌ์ฑ] |
|
1. ๋ฐ๋์ [๋์
๋ถ] - 1๊ฐ, [๋ณธ๋ก 1~5] - 5๊ฐ, [๊ฒฐ๋ก ] - 1๊ฐ๋ก ๊ตฌ์ฑํ์ฌ ์ถ๋ ฅํ๋ผ. |
|
2. ๋ฐ๋์ [๋์
๋ถ]์ [๊ฒฐ๋ก ]์ ์ ๋ชฉ์ด ์ค๋ณต๋์ง ์๋๋ก ์์ฑํ๋ผ. |
|
""" |
|
elif (category == "๊ฑด๊ฐ์ ๋ณด"): |
|
return """ |
|
# ๋ธ๋ก๊ทธ ์์ฃผ์ (Subtopic) ์์ฑ ๊ท์น(๊ฑด๊ฐ์ ๋ณด) |
|
##[๊ธฐ๋ณธ๊ท์น] |
|
1. ๋ฐ๋์ ํ๊ตญ์ด(ํ๊ธ)๋ก ์์ฑํ๋ผ. |
|
2. ๋๋ ๊ฐ์ฅ ์ฃผ๋ชฉ๋ฐ๋ ๋ง์ผํฐ์ด๋ฉฐ ๋ธ๋ก๊ทธ ๋ง์ผํ
์ ๋ฌธ๊ฐ์ด๋ค. |
|
3. ํนํ ๋๋ '๊ฑด๊ฐ, ์ํ ์ ๋ณด' ์ ๋ฌธ ๋ธ๋ก๊ทธ ๋ง์ผํฐ์ด๋ค. |
|
4. ์ ํํ๊ณ ์ ๋ฌธ์ ์ธ ์ ๋ณด ์ ๊ณต์ ์ด์ ์ ๋ง์ถ์ด ์์ฑํ๋ค. |
|
##[์์ฃผ์ ์์ฑ๊ท์น] |
|
1. [๊ธฐ๋ณธ๊ท์น]์ ๊ธฐ๋ณธ ์ ์ฉํ๋ผ. |
|
2. ๋ธ๋ก๊ทธ ๊ธ์ ์์ฑํ๊ธฐ ์ํ ์์ฃผ์ ๋ฅผ ์์ฑํ๋ผ. |
|
3. ์ ๊ณต๋ ์ฐธ๊ณ ๊ธ๊ณผ ๋ธ๋ก๊ทธ ์ฃผ์ , ์ ๋ชฉ์ ๋ฐํ์ผ๋ก ํต์ฌ ์ฃผ์ ๋ฅผ ํ์
ํ์ฌ ์์ฃผ์ ๋ฅผ ์์ฑํ๋ผ. |
|
4. ์ ์ฒด ๋งฅ๋ฝ์ ๋ง๊ฒ ์์ฃผ์ ๋ฅผ ์์ฑํ๋ผ. |
|
5. ์์ ๋ชฉ์ผ๋ก ์ฌ์ฉํ ์ ์๋๋ก 20์ ๋ด์ธ๋ก ์์ฑํ๋ผ. |
|
6. ๋
์๊ฐ ์ป๊ณ ์ ํ๋ ์ ํํ ์ ๋ณด์ ๊ฑด๊ฐํ ์ํ์ ์ ์งํ๋ ๋ฐ ํ์ํ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋๋ก ์์ฃผ์ ๋ฅผ ์์ฑํ๋ผ. |
|
7. ์์ฃผ์ ์ ๋ณธ๋ก ์ ๋ด์ฉ์ด ์ถฉ๋ถํ ์์ฑ๋ ์ ์๋ ์์ฃผ์ ๋ก ์ค์ ํ๋ผ. |
|
8. ๋ฐ๋์ [์์ฃผ์ ๊ตฌ์ฑ]์ ๋ง์ถฐ ์์ฃผ์ ๋ง ์ถ๋ ฅํ๋ผ. |
|
##[์์ฃผ์ ๊ตฌ์ฑ] |
|
1. ๋ฐ๋์ [๋์
๋ถ] - 1๊ฐ, [๋ณธ๋ก 1~5] - 5๊ฐ, [๊ฒฐ๋ก ] - 1๊ฐ๋ก ๊ตฌ์ฑํ์ฌ ์ถ๋ ฅํ๋ผ. |
|
2. ๋ฐ๋์ [๋์
๋ถ]์ [๊ฒฐ๋ก ]์ ์ ๋ชฉ์ด ์ค๋ณต๋์ง ์๋๋ก ์์ฑํ๋ผ. |
|
""" |
|
|
|
def get_blog_post_prompt(category): |
|
if (category == "์ผ๋ฐ"): |
|
return """ |
|
# ๋ธ๋ก๊ทธ ํ
์คํธ ์์ฑ ๊ท์น(์ผ๋ฐ) |
|
##[๊ธฐ๋ณธ๊ท์น] |
|
1. ๋ฐ๋์ ํ๊ตญ์ด(ํ๊ธ)๋ก ์์ฑํ๋ผ. |
|
2. ๋๋ ๊ฐ์ฅ ์ฃผ๋ชฉ๋ฐ๋ ๋ง์ผํฐ์ด๋ฉฐ ๋ธ๋ก๊ทธ ๋ง์ผํ
์ ๋ฌธ๊ฐ์ด๋ค. |
|
3. ํนํ ๋๋ '์ ๋ณด์ฑ(Informative)' ์ ๋ฌธ ๋ธ๋ก๊ทธ ๋ง์ผํ
์ ๋ฌธ๊ฐ์ด๋ค. |
|
4. ์ ๋ณด ์ ๊ณต์ ์ด์ ์ ๋ง์ถ์ด ์์ฑํ๋ค. |
|
##[ํ
์คํธ ์์ฑ ๊ท์น] |
|
1. ๋ฐ๋์ ์
๋ ฅ๋ [์์ฃผ์ ]์ ๋ง๊ฒ ํ
์คํธ๋ฅผ ์์ฑํ๋ผ. |
|
2. ์์ฃผ์ ์ [๋ณธ๋ก ] 5๊ฐ๋ฅผ ๊ฐ๊ฐ 300์ ์ด์์ผ๋ก ์์ฑํ๋ผ. |
|
3. ์์ฃผ์ ์ [๋ณธ๋ก ] ์ด 300์ ์ด์ ์์ฑ๋์ง ์๋๋ค๋ฉด, ์ ์ฒด๊ธ์ด 2000์ ์ด์๋๋๋ก ์์ฑํ๋ผ. |
|
4. ์ ์ฒด ๋งฅ๋ฝ์ ์ดํดํ๊ณ ๋ฌธ์ฅ์ ์ผ๊ด์ฑ์ ์ ์งํ๋ผ. |
|
5. ์ฃผ์ ์ ๋ง๋ ๋๋ค์, ํ๋ฅด์๋๋ฅผ ์ ์ฉํ์ฌ ์์ฑํ๋ผ. |
|
6. ์ ๊ณต๋ ์ฐธ๊ณ ๊ธ์ ์ดํฌ๋ฅผ ๋ฐ์ํ๋, [ํฌ์คํ
์คํ์ผ]์ ๋ง๊ฒ ์ ์ฉํ๋ผ. |
|
7. ์ ๋๋ก ์ฐธ๊ณ ๊ธ์ ํ๋ฌธ์ฅ ์ด์ ๊ทธ๋๋ก ์ถ๋ ฅํ์ง ๋ง ๊ฒ. |
|
8. ์ฃผ์ ์ ์ํฉ์ ๋ง๋ ์ ์ ํ ์ดํ๋ฅผ ์ ํํ๋ผ. |
|
9. ํ๊ธ ์ดํ์ ๋์ด๋๋ ์ฝ๊ฒ ์์ฑํ๋ผ. |
|
10. ์ ๋ ๋ฌธ์ฅ์ ๋์ '๋ต๋๋ค'๋ฅผ ์ฌ์ฉํ์ง ๋ง ๊ฒ. |
|
###[์ ๋ณด์ฑ ๋ธ๋ก๊ทธ ์์ฑ ๊ท์น] |
|
1. ๋
์๊ฐ ์ป๊ณ ์ ํ๋ ์ ์ฉํ ์ ๋ณด์ ํฅ๋ฏธ๋ก์ด ์ ๋ณด๋ฅผ ์ ๊ณตํ๋๋ก ์์ฑํ๋ผ. |
|
2. ๋
์์ ๊ณต๊ฐ์ ์ด๋์ด๋ด๊ณ ๊ถ๊ธ์ฆ์ ํด๊ฒฐํ๋๋ก ์์ฑํ๋ผ. |
|
3. ๋
์์ ๊ด์ฌ์ฌ๋ฅผ ์ถฉ์กฑ์ํค๋๋ก ์์ฑํ๋ผ. |
|
4. ๋
์์๊ฒ ์ด๋์ด ๋๋ ์ ๋ณด๋ฅผ ์์ฑํ๋ผ. |
|
##[์ ์ธ ๊ท์น] |
|
1. ๋ฐ๋์ ๋น์์ด ๋ฐ ์์ค(expletive, abusive language, slang)์ ์ ์ธํ๋ผ. |
|
2. ๋ฐ๋์ ์ฐธ๊ณ ๊ธ์ ๋งํฌ(URL)๋ ์ ์ธํ๋ผ. |
|
3. ์ฐธ๊ณ ๊ธ์์ '๋งํฌ๋ฅผ ํ์ธํด์ฃผ์ธ์'์ ๊ฐ์ ๋งํฌ ์ด๋์ ๋ฌธ๊ตฌ๋ ์ ์ธํ๋ผ. |
|
4. ์ฐธ๊ณ ๊ธ์ ์๋ ์์ฑ์, ํ์, ์ ํ๋ฒ, ๊ธฐ์(Writer, speaker, YouTuber, reporter)์ ์ด๋ฆ, ์ ์นญ, ๋๋ค์(Name, Nkickname)์ ๋ฐ๋์ ์ ์ธํ๋ผ. |
|
5. ๋ฐ๋์ ๋ฌธ์ฅ์ ๋๋ถ๋ถ์ด ์ด์ํ ํ๊ตญ์ด ํํ์ ์ ์ธํ๋ผ('์์', '๋ต๋๋ค', 'ํด์', 'ํด์ฃผ์ฃ ', '๋์ฃ ', '๋์ด์', '๊ณ ์' ๋ฑ.) |
|
""" |
|
elif (category == "๊ฑด๊ฐ์ ๋ณด"): |
|
return """ |
|
# ๋ธ๋ก๊ทธ ํ
์คํธ ์์ฑ ๊ท์น(๊ฑด๊ฐ์ ๋ณด) |
|
##[๊ธฐ๋ณธ๊ท์น] |
|
1. ๋ฐ๋์ ํ๊ตญ์ด(ํ๊ธ)๋ก ์์ฑํ๋ผ. |
|
2. ๋๋ ๊ฐ์ฅ ์ฃผ๋ชฉ๋ฐ๋ ๋ง์ผํฐ์ด๋ฉฐ ๋ธ๋ก๊ทธ ๋ง์ผํ
์ ๋ฌธ๊ฐ์ด๋ค. |
|
3. ํนํ ๋๋ '๊ฑด๊ฐ, ์ํ ์ ๋ณด' ์ ๋ฌธ ๋ธ๋ก๊ทธ ๋ง์ผํฐ์ด๋ค. |
|
4. ์ ํํ๊ณ ์ ๋ฌธ์ ์ธ ์ ๋ณด ์ ๊ณต์ ์ด์ ์ ๋ง์ถ์ด ์์ฑํ๋ค. |
|
##[ํ
์คํธ ์์ฑ ๊ท์น] |
|
1. ๋ฐ๋์ ์
๋ ฅ๋ [์์ฃผ์ ]์ ๋ง์ถฐ์ ํ
์คํธ๋ฅผ ์์ฑํ๋ผ. |
|
2. ๋ฐ๋์ ์
๋ ฅ๋ [์์ฃผ์ ]๋ ๋ณ๊ฒฝํ์ง ๋ง๊ณ ๊ทธ๋๋ก ์ถ๋ ฅํ๋ผ. |
|
3. ์์ฃผ์ ์ [๋์
๋ถ]๋ ๊ฐ๋ณ๊ฒ ์์ฑํ๋ ๊ณต๊ฐ๊ณผ ํฅ๋ฏธ, ๋ฌธ์ ์ ๊ธฐ, ๊ธ์ ๋ชฉ์ , ๋ณธ๋ฌธ์ผ๋ก ์์ฐ์ค๋ฝ๊ฒ ์ด์ด์ง๋ ์ ํ๋ฌธ์ฅ๋ฑ์ ์ถ๋ ฅํ๋ผ. |
|
3. ์์ฃผ์ ์ [๋ณธ๋ก ] 5๊ฐ์ ๋ด์ฉ์ด ๊ฐ๊ฐ 500์ ์ด์์ด ๋๋๋ก ์์ฑํ๋ผ. |
|
4. ๋ฐ๋์ ๋๊ฐ ์์ฑํ ์ ์ฒด๊ธ์ด 2500์ ์ด์์ด ๋๋๋ก ์์ฑํ๋ผ. |
|
5. ์ ์ฒด ๋งฅ๋ฝ์ ์ดํดํ๊ณ ๋ฌธ์ฅ์ ์ผ๊ด์ฑ์ ์ ์งํ๋ผ. |
|
6. ์ฐธ๊ณ ๊ธ์ ๋ฐํ์ผ๋ก ์์ฑํ ๊ธ์ ๋ง๋ ๋๋ค์, ํ๋ฅด์๋๋ฅผ ์ ์ฉํ์ฌ ์์ฑํ๋ผ. |
|
7. ์ดํฌ๋ ์ ๊ณต๋ ์ฐธ๊ณ ๊ธ์ ์ดํฌ๋ฅผ ๋ฐ์ํ๋, '๊ฑด๊ฐ, ์ํ ์ ๋ณด' ์ ๋ฌธ ๋ธ๋ก๊ทธ ๋ง์ผํฐ๋ก์ ์์ฑํ๋ผ. |
|
8. ์ ๋๋ก ์ฐธ๊ณ ๊ธ์ ํ๋ฌธ์ฅ ์ด์ ๊ทธ๋๋ก ์ถ๋ ฅํ์ง ๋ง ๊ฒ. |
|
9. ์ฃผ์ ์ ์ํฉ์ ๋ง๋ ์ ์ ํ ์ดํ๋ฅผ ์ ํํ๋ผ. |
|
###[์ ๋ณด์ฑ ๋ธ๋ก๊ทธ ์์ฑ ๊ท์น] |
|
1. ๋
์๊ฐ ์ป๊ณ ์ ํ๋ ์ ํํ ์ ๋ณด์ ๊ฑด๊ฐํ ์ํ์ ์ ์งํ๋ ๋ฐ ํ์ํ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋๋ก ์์ฃผ์ ์ ๋ง๊ฒ ๋ด์ฉ์ ์์ฑํ๋ผ. |
|
2. ๋
์์ ๊ณต๊ฐ์ ์ด๋์ด๋ด๊ณ ๊ถ๊ธ์ฆ์ ํด๊ฒฐํ๋๋ก ์์ฑํ๋ผ. |
|
3. ๋
์์ ๊ด์ฌ์ฌ๋ฅผ ์ถฉ์กฑ์ํค๋๋ก ์์ฑํ๋ผ. |
|
4. ๋
์์๊ฒ ์ด๋์ด ๋๋ ์ ๋ณด๋ฅผ ์์ฑํ๋ผ. |
|
##[์ ์ธ ๊ท์น] |
|
1. ๋ฐ๋์ ์ฐธ๊ณ ๊ธ์ ๋งํฌ(URL)๋ ์ ์ธํ๋ผ. |
|
2. ์ฐธ๊ณ ๊ธ์์ '๋งํฌ๋ฅผ ํ์ธํด์ฃผ์ธ์'์ ๊ฐ์ ๋งํฌ ์ด๋์ ๋ฌธ๊ตฌ๋ ์ ์ธํ๋ผ. |
|
3. ์ฐธ๊ณ ๊ธ์ ์๋ ์์ฑ์, ํ์, ์ ํ๋ฒ, ๊ธฐ์(Writer, speaker, YouTuber, reporter)์ ์ด๋ฆ, ์ ์นญ, ๋๋ค์(Name, Nkickname)์ ๋ฐ๋์ ์ ์ธํ๋ผ. |
|
""" |
|
|
|
def get_style_prompt(style): |
|
prompts = { |
|
"์น๊ทผํ": """ |
|
#์น๊ทผํ ๋ธ๋ก๊ทธ ํฌ์คํ
์คํ์ผ ๊ฐ์ด๋ |
|
1. ํค๊ณผ ์ด์กฐ |
|
- ๋ํํ๋ฏ ํธ์ํ๊ณ ์น๊ทผํ ๋งํฌ ์ฌ์ฉ |
|
- ๋
์๋ฅผ "์ฌ๋ฌ๋ถ" ๋๋ "๋
์๋๋ค"๋ก ์ง์นญ |
|
- ์ ์ ํ ์ด๋ชจ์ง๋ฅผ sparseํ๊ฒ ์ฌ์ฉํ์ฌ ์น๊ทผ๊ฐ ํํ |
|
2. ๋ฌธ์ฅ ๋ฐ ๋ด์ฉ ๊ตฌ์ฑ |
|
- ์งง๊ณ ๊ฐ๊ฒฐํ ๋ฌธ์ฅ ์์ฃผ๋ก ์์ฑ |
|
- ๊ตฌ์ด์ฒด ํํ ์ฌ์ฉ (์: "~ํ์ด์", "~์ธ ๊ฒ ๊ฐ์์") |
|
- '~๋๋ค', '~ํ์ฃ '๋ ์ฌ์ฉํ์ง ๋ง ๊ฒ. |
|
- ๊ฐ์ธ์ ์ธ ๊ฒฝํ์ด๋ ์ผํ๋ก ์์ |
|
- ์ค์ํ์์ ์ฝ๊ฒ ์ ์ฉํ ์ ์๋ ํ ์ ๊ณต |
|
- ๋
์์ ๊ณต๊ฐ์ ์ป์ ์ ์๋ ์ฌ๋ก ํฌํจ |
|
3. ์ฉ์ด ๋ฐ ์ค๋ช
๋ฐฉ์ |
|
- ์ ๋ฌธ ์ฉ์ด ๋์ ์ฌ์ด ๋จ์ด๋ก ํ์ด์ ์ค๋ช
|
|
- ๋น์ ๋ ์์ ๋ฅผ ํ์ฉํ์ฌ ๋ณต์กํ ๊ฐ๋
์ค๋ช
|
|
- ์์ฌ์๋ฌธ๋ฌธ ํ์ฉํ์ฌ ๋
์์ ์ํตํ๋ ๋๋ ์ฃผ๊ธฐ |
|
4. ๋
์์์ ์ํธ์์ฉ |
|
- ๋
์์ ์๊ฒฌ์ ๋ฌผ์ด๋ณด๋ ์ง๋ฌธ ํฌํจ |
|
- ๋๊ธ ๋ฌ๊ธฐ๋ฅผ ๋
๋ คํ๋ ๋ฌธ๊ตฌ ์ฌ์ฉ |
|
5. ์ด๋ชจ์ง ํ์ฉ |
|
- ์ฃผ์ ํฌ์ธํธ๋ ์๋ก์ด ์น์
์ ์์ํ ๋๋ง ๊ด๋ จ ์ด๋ชจ์ง ์ฌ์ฉ |
|
- ์ ์ฒด ๊ธ์์ 3-5๊ฐ ์ ๋์ ์ด๋ชจ์ง๋ง ์ฌ์ฉํ์ฌ ๊ณผ๋ํ์ง ์๊ฒ ์ ์ง |
|
6. ๋ง๋ฌด๋ฆฌ |
|
- ์น๊ทผํ๊ณ ๊ฒฉ๋ คํ๋ ํค์ผ๋ก ๋ง๋ฌด๋ฆฌ |
|
- ๋ค์ ํฌ์คํ
์ ๋ํ ๊ธฐ๋๊ฐ ์ ๋ฐ |
|
์ฃผ์์ฌํญ: ๋๋ฌด ๊ฐ๋ฒผ์ด ํค์ ์ง์ํ๊ณ , ์ฃผ์ ์ ์ค์์ฑ์ ํด์น์ง ์๋ ์ ์์ ์น๊ทผํจ ์ ์ง |
|
์์: "์ฌ๋ฌ๋ถ, ์ค๋ ํ๋ฃจ๋ ์ด๋ ์
จ๋์? ๐ ์ ๋ ์ค๋ ์ฌ๋ฏธ์๋ ๊ฒฝํ์ ํ์ด์. ๋ฐ๋ก '๋ฏธ๋๋ฉ ๋ผ์ดํ'์ ๋์ ํด๋ณธ ๊ฑด๋ฐ์. ์ฒ์์๋ ์ข ๋ง๋งํ์ง๋ง, ์๊ฐ๋ณด๋ค ์ฆ๊ฑฐ์ด ๊ฒฝํ์ด์์ด์! ์ฌ๋ฌ๋ถ๋ ํ๋ฒ ๋ฐ๋ผํด๋ณด์๊ฒ ์ด์? ์ ๊ฐ ์๊ฒ ๋ ๊ฟํ๋ค์ ํ๋ํ๋ ์๋ ค๋๋ฆด๊ฒ์. |
|
""", |
|
"์ผ๋ฐ": """ |
|
#์ผ๋ฐ์ ์ธ ๋ธ๋ก๊ทธ ํฌ์คํ
์คํ์ผ ๊ฐ์ด๋ |
|
1. ํค๊ณผ ์ด์กฐ |
|
- ์ค๋ฆฝ์ ์ด๊ณ ๊ฐ๊ด์ ์ธ ํค ์ ์ง |
|
- ์ ์ ํ ์กด๋๋ง ์ฌ์ฉ (์: "~ํฉ๋๋ค", "~์
๋๋ค") |
|
2. ๋ด์ฉ ๊ตฌ์กฐ ๋ฐ ์ ๊ฐ |
|
- ๋ช
ํํ ์ฃผ์ ์ ์๋ก ์์ |
|
- ๋
ผ๋ฆฌ์ ์ธ ์์๋ก ์ ๋ณด ์ ๊ฐ |
|
- ์ฃผ์ ํฌ์ธํธ๋ฅผ ๊ฐ์กฐํ๋ ์์ ๋ชฉ ํ์ฉ |
|
- ์ ์ ํ ๊ธธ์ด์ ๋จ๋ฝ์ผ๋ก ๊ตฌ์ฑ |
|
3. ์ฉ์ด ๋ฐ ์ค๋ช
๋ฐฉ์ |
|
- ์ผ๋ฐ์ ์ผ๋ก ์ดํดํ๊ธฐ ์ฌ์ด ์ฉ์ด ์ ํ |
|
- ํ์์ ๊ฐ๋จํ ์ค๋ช
์ถ๊ฐ |
|
- ๊ฐ๊ด์ ์ธ ์ ๋ณด ์ ๊ณต์ ์ค์ |
|
4. ํ
์คํธ ๊ตฌ์กฐํ |
|
- ๋ถ๋ฆฟ ํฌ์ธํธ๋ ๋ฒํธ ๋งค๊ธฐ๊ธฐ๋ฅผ ํ์ฉํ์ฌ ์ ๋ณด ๊ตฌ์กฐํ |
|
- ์ค์ํ ์ ๋ณด๋ ๊ตต์ ๊ธ์จ๋ ๊ธฐ์ธ์๊ผด๋ก ๊ฐ์กฐ |
|
5. ๋
์ ์ํธ์์ฉ |
|
- ์ ์ ํ ๋
์์ ์๊ฐ์ ๋ฌป๋ ์ง๋ฌธ ํฌํจ |
|
- ์ถ๊ฐ ์ ๋ณด๋ฅผ ์ฐพ์ ์ ์๋ ํค์๋ ์ ์ |
|
6. ๋ง๋ฌด๋ฆฌ |
|
- ์ฃผ์ ๋ด์ฉ ๊ฐ๋จํ ์์ฝ |
|
- ์ถ๊ฐ ์ ๋ณด์ ๋ํ ์๋ด ์ ๊ณต |
|
์ฃผ์์ฌํญ: ๋๋ฌด ๋ฑ๋ฑํ๊ฑฐ๋ ์ง๋ฃจํ์ง ์๋๋ก ๊ท ํ ์ ์ง |
|
์์: "์ต๊ทผ ํ๊ฒฝ ๋ฌธ์ ๊ฐ ๋๋๋๋ฉด์ '์ ๋ก ์จ์ด์คํธ' ๋ผ์ดํ์คํ์ผ์ ๋ํ ๊ด์ฌ์ด ๋์์ง๊ณ ์์ต๋๋ค. ์ ๋ก ์จ์ด์คํธ๋ ์ผ์์ํ์์ ๋ฐ์ํ๋ ์ฐ๋ ๊ธฐ๋ฅผ ์ต์ํํ๋ ์ํ ๋ฐฉ์์ ๋งํฉ๋๋ค. ์ด ๊ธ์์๋ ์ ๋ก ์จ์ด์คํธ์ ๊ฐ๋
, ์ค์ฒ ๋ฐฉ๋ฒ, ๊ทธ๋ฆฌ๊ณ ๊ทธ ํจ๊ณผ์ ๋ํด ์์๋ณด๊ฒ ์ต๋๋ค. ๋จผ์ ์ ๋ก ์จ์ด์คํธ์ ์ ์๋ถํฐ ์ดํด๋ณด๋ฉด... |
|
""", |
|
"์ ๋ฌธ์ ์ธ": """ |
|
#์ ๋ฌธ์ ์ธ ๋ธ๋ก๊ทธ ํฌ์คํ
์คํ์ผ ๊ฐ์ด๋ |
|
1. ํค๊ณผ ๊ตฌ์กฐ |
|
- ๊ณต์์ ์ด๊ณ ํ์ ์ ์ธ ํค ์ฌ์ฉ |
|
- ๊ฐ๊ด์ ์ด๊ณ ๋ถ์์ ์ธ ์ ๊ทผ ์ ์ง |
|
- ๋ช
ํํ ์๋ก , ๋ณธ๋ก , ๊ฒฐ๋ก ๊ตฌ์กฐ |
|
- ์ฒด๊ณ์ ์ธ ๋
ผ์ ์ ๊ฐ |
|
- ์ธ๋ถ ์น์
์ ์ํ ๋ช
ํํ ์์ ๋ชฉ ์ฌ์ฉ |
|
2. ๋ด์ฉ ๊ตฌ์ฑ ๋ฐ ์ ๊ฐ |
|
- ๋ณต์กํ ๊ฐ๋
์ ์ ํํ ์ ๋ฌํ ์ ์๋ ๋ฌธ์ฅ ๊ตฌ์กฐ ์ฌ์ฉ |
|
- ๋
ผ๋ฆฌ์ ์ฐ๊ฒฐ์ ์ํ ์ ํ์ด ํ์ฉ |
|
- ํด๋น ๋ถ์ผ์ ์ ๋ฌธ ์ฉ์ด ์ ๊ทน ํ์ฉ (ํ์์ ๊ฐ๋ตํ ์ค๋ช
์ ๊ณต) |
|
- ์ฌ์ธต์ ์ธ ๋ถ์๊ณผ ๋นํ์ ์ฌ๊ณ ์ ๊ฐ |
|
- ๋ค์ํ ๊ด์ ์ ์ ๋ฐ ๋น๊ต |
|
3. ๋ฐ์ดํฐ ๋ฐ ๊ทผ๊ฑฐ ํ์ฉ |
|
- ํต๊ณ, ์ฐ๊ตฌ ๊ฒฐ๊ณผ, ์ ๋ฌธ๊ฐ ์๊ฒฌ ๋ฑ ์ ๋ขฐํ ์ ์๋ ์ถ์ฒ ์ธ์ฉ |
|
- ํ์์ ๊ฐ์ฃผ๋ ์ฐธ๊ณ ๋ฌธํ ๋ชฉ๋ก ํฌํจ |
|
- ์์น ๋ฐ์ดํฐ๋ ํ
์คํธ๋ก ๋ช
ํํ ์ค๋ช
|
|
4. ํ
์คํธ ๊ตฌ์กฐํ |
|
- ๋
ผ๋ฆฌ์ ๊ตฌ์กฐ๋ฅผ ๊ฐ์กฐํ๊ธฐ ์ํด ๋ฒํธ ๋งค๊ธฐ๊ธฐ ์ฌ์ฉ |
|
- ํต์ฌ ๊ฐ๋
์ด๋ ์ฉ์ด๋ ๊ธฐ์ธ์๊ผด๋ก ๊ฐ์กฐ |
|
- ๊ธด ์ธ์ฉ๋ฌธ์ ๋ค์ฌ์ฐ๊ธฐ๋ก ๊ตฌ๋ถ |
|
5. ๋ง๋ฌด๋ฆฌ |
|
- ํต์ฌ ๋
ผ์ ์ฌ๊ฐ์กฐ |
|
- ํฅํ ์ฐ๊ตฌ ๋ฐฉํฅ์ด๋ ์ค๋ฌด์ ํจ์ ์ ์ |
|
์ฃผ์์ฌํญ: ์ ๋ฌธ์ฑ์ ์ ์งํ๋, ์์ ํ ์ดํดํ๊ธฐ ์ด๋ ค์ด ์์ค์ ์ง์ |
|
์์: "๋ณธ ์ฐ๊ตฌ์์๋ ์ธ๊ณต์ง๋ฅ(AI)์ ์ค๋ฆฌ์ ํจ์์ ๋ํด ๊ณ ์ฐฐํ๋ค. ํนํ, ์์จ์ฃผํ ์๋์ฐจ์ ์์ฌ๊ฒฐ์ ์๊ณ ๋ฆฌ์ฆ์์ ๋ฐ์ํ ์ ์๋ ์ค๋ฆฌ์ ๋๋ ๋ง์ ์ด์ ์ ๋ง์ถ๋ค. Bonnefon et al. (2016)์ ์ฐ๊ตฌ์ ๋ฐ๋ฅด๋ฉด, ์์จ์ฃผํ ์ฐจ๋์ ์๊ณ ๋ฆฌ์ฆ์ด ์ง๋ฉดํ ์ ์๋ ์ค๋ฆฌ์ ์ ํ์ ๋ณต์ก์ฑ์ด ์ง์ ๋ ๋ฐ ์๋ค. ๋ณธ๊ณ ์์๋ ์ด๋ฌํ ์ค๋ฆฌ์ ๋๋ ๋ง๋ฅผ ์ธ ๊ฐ์ง ์ฃผ์ ๊ด์ ์์ ๋ถ์ํ๋ค: 1) ๊ณต๋ฆฌ์ฃผ์์ ์ ๊ทผ, 2) ์๋ฌด๋ก ์ ์ ๊ทผ, 3) ๋ ์ค๋ฆฌ์ ์ ๊ทผ. ๊ฐ ์ ๊ทผ๋ฒ์ ์ฅ๋จ์ ์ ๋น๊ต ๋ถ์ํ๊ณ , ์ด๋ฅผ ๋ฐํ์ผ๋ก ์์จ์ฃผํ ์ฐจ๋์ ์ค๋ฆฌ์ ์์ฌ๊ฒฐ์ ํ๋ ์์ํฌ๋ฅผ ์ ์ํ๊ณ ์ ํ๋ค... |
|
""" |
|
} |
|
return prompts.get(style, "ํฌ์คํ
์คํ์ผ ํ๋กฌํํธ") |
|
|
|
def get_style_description(style): |
|
descriptions = { |
|
"์น๊ทผํ": "๋
์์ ๊ฐ๊น์ด ์น๊ตฌ์ฒ๋ผ ๋ํํ๋ ๋ฏํ ์น๊ทผํ ์คํ์ผ์
๋๋ค.", |
|
"์ผ๋ฐ": "์ผ๋ฐ์ ์ด๊ณ ์ค๋ฆฝ์ ์ธ ํค์ผ๋ก ์ ๋ณด๋ฅผ ์ ๋ฌํ๋ ์คํ์ผ์
๋๋ค.", |
|
"์ ๋ฌธ์ ์ธ": "์ ๋ฌธ๊ฐ์ ์๊ฐ์์ ๊น์ด ์๋ ์ ๋ณด๋ฅผ ์ ๋ฌํ๋ ์คํ์ผ์
๋๋ค." |
|
} |
|
return descriptions.get(style, "ํฌ์คํ
์คํ์ผ์ ์ ํํ์ธ์.") |
|
|
|
def update_prompts_and_description(category, style): |
|
title_prompt = get_title_prompt(category) |
|
outline_prompt = get_outline_prompt(category) |
|
blog_post_prompt = get_blog_post_prompt(category) |
|
style_prompt = get_style_prompt(style) |
|
style_description = get_style_description(style) |
|
return style_description, |
|
|
|
|
|
|
|
class PDF(FPDF): |
|
def __init__(self): |
|
super().__init__() |
|
current_dir = os.path.dirname(__file__) |
|
self.add_font("NanumGothic", "", os.path.join(current_dir, "NanumGothic.ttf"), uni=True) |
|
self.add_font("NanumGothic", "B", os.path.join(current_dir, "NanumGothicBold.ttf"), uni=True) |
|
self.add_font("NanumGothicExtraBold", "", os.path.join(current_dir, "NanumGothicExtraBold.ttf"), uni=True) |
|
self.add_font("NanumGothicLight", "", os.path.join(current_dir, "NanumGothicLight.ttf"), uni=True) |
|
|
|
def header(self): |
|
self.set_font('NanumGothic', '', 10) |
|
|
|
def footer(self): |
|
self.set_y(-15) |
|
self.set_font('NanumGothic', '', 8) |
|
self.cell(0, 10, f'Page {self.page_no()}', 0, 0, 'C') |
|
|
|
def save_to_pdf(blog_post): |
|
pdf = PDF() |
|
pdf.add_page() |
|
|
|
lines = blog_post.split('\n') |
|
title = lines[0].strip() |
|
content = '\n'.join(lines[1:]).strip() |
|
|
|
filename = format_filename(title) + ".pdf" |
|
|
|
pdf.set_font("NanumGothic", 'B', size=14) |
|
pdf.cell(0, 10, title, ln=True, align='C') |
|
pdf.ln(10) |
|
|
|
pdf.set_font("NanumGothic", '', size=11) |
|
pdf.multi_cell(0, 5, content) |
|
|
|
print(f"Saving PDF as: {filename}") |
|
pdf.output(filename) |
|
return filename |
|
|
|
def format_filename(text): |
|
text = re.sub(r'[^\w\s-]', '', text) |
|
return text[:50].strip() |
|
|
|
|
|
def save_content_to_pdf(blog_post): |
|
return save_to_pdf(blog_post) |
|
|
|
title = "๋ธ๋ก๊ฑฐ(๊ตฌ๊ธ) ์๋ ํฌ์คํ
-์๋-One ID-๋ณต์ ํฌ์คํ
์์ฑ/ ํฌ์คํ
๊ฒ์ฌ(์) ๋งํฌ ํด๋ฆญ: https://carecures.blogspot.com \n" |
|
|
|
def update_prompts_and_description(category, style): |
|
title_prompt = get_title_prompt(category) |
|
outline_prompt = get_outline_prompt(category) |
|
blog_post_prompt = get_blog_post_prompt(category) |
|
style_prompt = get_style_prompt(style) |
|
style_description = get_style_description(style) |
|
return style_description |
|
|
|
|
|
WEBHOOK_URL = os.getenv("WEBHOOK_URL") |
|
BLOGGER_ID = os.getenv("BLOGGER_ID") |
|
|
|
PEXELS_API_KEY = "5woz23MGx1QrSY0WHFb0BRi29JvbXPu97Hg0xnklYgHUI8G0w23FKH62" |
|
PEXELS_API_URL = "https://api.pexels.com/v1/search" |
|
|
|
|
|
translator = pipeline("translation", model="Helsinki-NLP/opus-mt-ko-en") |
|
|
|
def get_image_url(topic): |
|
try: |
|
translated = translator(topic, max_length=40)[0]['translation_text'] |
|
keywords = ' '.join(translated.split()[:2]) |
|
except Exception as e: |
|
logger.error(f"๋ฒ์ญ ์ค ์ค๋ฅ ๋ฐ์: {str(e)}") |
|
keywords = ' '.join(topic.split()[:2]) |
|
|
|
logger.debug(f"๊ฒ์ ํค์๋: {keywords}") |
|
|
|
headers = { |
|
"Authorization": PEXELS_API_KEY |
|
} |
|
params = { |
|
"query": keywords, |
|
"per_page": 60, |
|
} |
|
|
|
try: |
|
response = requests.get(PEXELS_API_URL, headers=headers, params=params) |
|
logger.debug(f"Pexels API ์๋ต ์ํ ์ฝ๋: {response.status_code}") |
|
|
|
if response.status_code == 200: |
|
data = response.json() |
|
logger.debug(f"Pexels API ์๋ต ๋ฐ์ดํฐ: {data}") |
|
|
|
if data['photos']: |
|
|
|
random_photo = random.choice(data['photos']) |
|
return random_photo['src']['large2x'] |
|
else: |
|
logger.warning(f"'{keywords}' ๊ด๋ จ ์ด๋ฏธ์ง๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.") |
|
return None |
|
else: |
|
logger.error(f"Pexels API ์ค๋ฅ: {response.status_code}") |
|
return None |
|
except Exception as e: |
|
logger.error(f"์ด๋ฏธ์ง ๊ฒ์ ์ค ์ค๋ฅ ๋ฐ์: {str(e)}") |
|
return None |
|
|
|
|
|
|
|
def convert_markdown_images(content): |
|
logger.debug("์๋ณธ ๋ด์ฉ: %s", content) |
|
|
|
|
|
markdown_pattern = r'!\[([^\]]*)\]\(([^)]+)\)' |
|
content = re.sub(markdown_pattern, r'<img alt="\1" src="\2">', content) |
|
|
|
|
|
url_pattern = r'(https?://\S+?\.(jpg|jpeg|png|gif))' |
|
content = re.sub(url_pattern, r'<img src="\1">', content) |
|
|
|
logger.debug("๋ณํ๋ ๋ด์ฉ: %s", content) |
|
|
|
return content |
|
|
|
|
|
def process_all_titles(category, style, topic, num_titles, progress=gr.Progress()): |
|
title_suggestions, _ = suggest_title(category, style, topic, "", "", "") |
|
titles = title_suggestions.split('\n') |
|
|
|
titles = [title.strip() for title in titles if title.strip() and not title.strip().startswith('###')] |
|
titles = [title for title in titles if "๋ธ๋ก๊ทธ" not in title and "์ ๋ชฉ" not in title] |
|
|
|
results = [] |
|
for i, title in enumerate(titles[:num_titles], 1): |
|
progress(i / num_titles, desc=f"์ฒ๋ฆฌ ์ค: {i}/{num_titles}") |
|
try: |
|
image_url_1 = get_image_url(topic) |
|
image_url_2 = get_image_url(topic) |
|
|
|
_, _, _, _, _, blog_content, _ = fetch_references_and_generate_all_steps(category, style, topic, title) |
|
|
|
if blog_content.startswith("API ํธ์ถ ์คํจ"): |
|
result = f"์ ๋ชฉ: {title}\n์์ฑ ์คํจ: {blog_content}\n\n" |
|
else: |
|
if image_url_1: |
|
blog_content = f'<img src="{image_url_1}" alt="{topic} 1" style="max-width:100%; height:auto;">\n\n{blog_content}' |
|
if image_url_2: |
|
blog_content = f'{blog_content}\n\n<img src="{image_url_2}" alt="{topic} 2" style="max-width:100%; height:auto;">' |
|
|
|
send_result = send_to_blogger(title, blog_content) |
|
result = f"์ ๋ชฉ: {title}\n์ ์ก ๊ฒฐ๊ณผ: {send_result}\n์ฌ์ฉ๋ ์ด๋ฏธ์ง URL 1: {image_url_1 if image_url_1 else '์ด๋ฏธ์ง ์์'}\n์ฌ์ฉ๋ ์ด๋ฏธ์ง URL 2: {image_url_2 if image_url_2 else '์ด๋ฏธ์ง ์์'}\n\n" |
|
|
|
results.append(result) |
|
yield f"์งํ ์ํฉ: {i}/{num_titles}\n\n" + "\n".join(results) |
|
except Exception as e: |
|
logger.error("์ ๋ชฉ '%s' ์ฒ๋ฆฌ ์ค ์ค๋ฅ ๋ฐ์: %s", title, str(e)) |
|
result = f"์ ๋ชฉ: {title}\n์ฒ๋ฆฌ ์ค ์ค๋ฅ ๋ฐ์: {str(e)}\n\n" |
|
results.append(result) |
|
yield f"์งํ ์ํฉ: {i}/{num_titles}\n\n" + "\n".join(results) |
|
|
|
time.sleep(5) |
|
|
|
yield f"์๋ฃ: {num_titles}/{num_titles}\n\n" + "\n".join(results) |
|
|
|
|
|
|
|
def send_to_blogger(blog_title, blog_content): |
|
if not WEBHOOK_URL: |
|
logger.error("WEBHOOK_URL์ด ์ค์ ๋์ง ์์์ต๋๋ค.") |
|
return "WEBHOOK_URL์ด ์ค์ ๋์ง ์์ ํฌ์คํ
์ ์ ์กํ ์ ์์ต๋๋ค." |
|
|
|
|
|
blog_content = html.unescape(blog_content) |
|
|
|
payload = { |
|
"blogger_id": BLOGGER_ID, |
|
"title": blog_title, |
|
"content": blog_content |
|
} |
|
|
|
try: |
|
logger.debug("๋ธ๋ก๊ฑฐ์ ์ ์กํ ํ์ด๋ก๋: %s", payload) |
|
|
|
response = requests.post(WEBHOOK_URL, json=payload) |
|
logger.debug("๋ธ๋ก๊ฑฐ ์๋ต: %s, %s", response.status_code, response.text) |
|
|
|
if response.status_code == 200: |
|
return "ํฌ์คํ
์ด ์ฑ๊ณต์ ์ผ๋ก ์ ์ก๋์์ต๋๋ค." |
|
else: |
|
return f"ํฌ์คํ
์ ์ก ์คํจ. ์ํ ์ฝ๋: {response.status_code}, ์๋ต: {response.text}" |
|
except requests.exceptions.RequestException as e: |
|
logger.error("๋ธ๋ก๊ฑฐ์ ์ ์ก ์ค ์ค๋ฅ ๋ฐ์: %s", str(e)) |
|
return f"๋คํธ์ํฌ ์ค๋ฅ ๋ฐ์: {str(e)}" |
|
except Exception as e: |
|
logger.error("๋ธ๋ก๊ทธ์ ์ ์ก ์ค ์์์น ๋ชปํ ์ค๋ฅ ๋ฐ์: %s", str(e)) |
|
return f"์ค๋ฅ ๋ฐ์: {str(e)}" |
|
|
|
css = """ |
|
footer { |
|
visibility: hidden; |
|
} |
|
""" |
|
|
|
|
|
with gr.Blocks(theme="Nymbo/Nymbo_Theme", css=css) as demo: |
|
gr.Markdown(f"# {title}") |
|
|
|
gr.Markdown("### 1๋จ๊ณ : ํฌ์คํ
์นดํ
๊ณ ๋ฆฌ๋ฅผ ์ง์ ํด์ฃผ์ธ์") |
|
category = gr.Radio(choices=["์ผ๋ฐ", "๊ฑด๊ฐ์ ๋ณด"], label="ํฌ์คํ
์นดํ
๊ณ ๋ฆฌ", value="์ผ๋ฐ") |
|
|
|
gr.Markdown("### 2๋จ๊ณ: ํฌ์คํ
์คํ์ผ์ ์ ํํด์ฃผ์ธ์") |
|
style = gr.Radio(choices=["์น๊ทผํ", "์ผ๋ฐ", "์ ๋ฌธ์ ์ธ"], label="ํฌ์คํ
์คํ์ผ", value="์น๊ทผํ") |
|
style_description = gr.Markdown(f"_{get_style_description('์น๊ทผํ')}_", elem_id="style-description") |
|
|
|
gr.Markdown("### 3๋จ๊ณ : ๋ธ๋ก๊ทธ ์ฃผ์ , ๋๋ ํค์๋๋ฅผ ์์ธํ ์
๋ ฅํ์ธ์") |
|
topic = gr.Textbox(label="๋ธ๋ก๊ทธ ์ฃผ์ ", placeholder="์์: 8์ ๊ตญ๋ด ์ฌํ์ง ์ถ์ฒ") |
|
|
|
gr.Markdown("### 4๋จ๊ณ : ์๋ ์์ฑ ๋ฐ ์ ์กํ ๋ธ๋ก๊ทธ ์๋ฅผ ์ ํํ์ธ์") |
|
num_titles = gr.Slider(minimum=1, maximum=2, value=2, step=1, label="ํฌ์คํ
๊ฑด") |
|
|
|
start_btn = gr.Button("์์") |
|
result_output = gr.Textbox(label="์ฒ๋ฆฌ ๊ฒฐ๊ณผ", lines=20) |
|
|
|
start_btn.click( |
|
fn=process_all_titles, |
|
inputs=[category, style, topic, num_titles], |
|
outputs=[result_output] |
|
) |
|
|
|
category.change(fn=update_prompts_and_description, inputs=[category, style], outputs=[style_description]) |
|
style.change(fn=update_prompts_and_description, inputs=[category, style], outputs=[style_description]) |
|
|
|
demo.launch() |