project11 / utils.py
kmg
Integrate services
487eb4e
"""
์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜๋“ค
"""
import random
import requests
from PIL import Image, ImageDraw, ImageFont
import io
from config import CHATBOT_RESPONSES, MEME_TEMPLATES
def create_meme_image(template_info, top_text, bottom_text):
"""๋ฐˆ ์ด๋ฏธ์ง€ ์ƒ์„ฑ"""
try:
# ๊ธฐ๋ณธ ์บ”๋ฒ„์Šค ์ƒ์„ฑ (์‹ค์ œ ํ™˜๊ฒฝ์—์„œ๋Š” ํ…œํ”Œ๋ฆฟ ์ด๋ฏธ์ง€ ๋กœ๋“œ)
width, height = 500, 400
img = Image.new('RGB', (width, height), color='white')
draw = ImageDraw.Draw(img)
# ํฐํŠธ ์„ค์ • (๊ธฐ๋ณธ ํฐํŠธ ์‚ฌ์šฉ)
try:
font_large = ImageFont.truetype("arial.ttf", 32)
font_small = ImageFont.truetype("arial.ttf", 24)
except:
font_large = ImageFont.load_default()
font_small = ImageFont.load_default()
# ๋ฐฐ๊ฒฝ ๊ทธ๋ผ๋ฐ์ด์…˜ ํšจ๊ณผ
for y in range(height):
color_value = int(255 * (y / height))
color = (color_value, color_value, 255)
draw.line([(0, y), (width, y)], fill=color)
# ํ…์ŠคํŠธ ์ถ”๊ฐ€
if top_text:
# ์ƒ๋‹จ ํ…์ŠคํŠธ
text_width = draw.textlength(top_text, font=font_large)
x = (width - text_width) // 2
y = 30
# ํ…์ŠคํŠธ ์™ธ๊ณฝ์„ 
for dx in [-1, 0, 1]:
for dy in [-1, 0, 1]:
if dx != 0 or dy != 0:
draw.text((x+dx, y+dy), top_text, font=font_large, fill='black')
draw.text((x, y), top_text, font=font_large, fill='white')
if bottom_text:
# ํ•˜๋‹จ ํ…์ŠคํŠธ
text_width = draw.textlength(bottom_text, font=font_large)
x = (width - text_width) // 2
y = height - 70
# ํ…์ŠคํŠธ ์™ธ๊ณฝ์„ 
for dx in [-1, 0, 1]:
for dy in [-1, 0, 1]:
if dx != 0 or dy != 0:
draw.text((x+dx, y+dy), bottom_text, font=font_large, fill='black')
draw.text((x, y), bottom_text, font=font_large, fill='white')
return img
except Exception as e:
print(f"์ด๋ฏธ์ง€ ์ƒ์„ฑ ์˜ค๋ฅ˜: {e}")
return create_error_image(str(e))
def create_error_image(error_msg):
"""์—๋Ÿฌ ์ด๋ฏธ์ง€ ์ƒ์„ฑ"""
img = Image.new('RGB', (400, 300), color='red')
draw = ImageDraw.Draw(img)
try:
font = ImageFont.load_default()
draw.text((50, 150), f"์˜ค๋ฅ˜: {error_msg}", font=font, fill='white')
except:
pass
return img
def add_text_to_image(img, text, position, font_size=32, color='white'):
"""์ด๋ฏธ์ง€์— ํ…์ŠคํŠธ ์ถ”๊ฐ€"""
draw = ImageDraw.Draw(img)
try:
font = ImageFont.truetype("arial.ttf", font_size)
except:
font = ImageFont.load_default()
x, y = position
# ์™ธ๊ณฝ์„  ํšจ๊ณผ
for dx in [-1, 0, 1]:
for dy in [-1, 0, 1]:
if dx != 0 or dy != 0:
draw.text((x+dx, y+dy), text, font=font, fill='black')
draw.text((x, y), text, font=font, fill=color)
return img
def generate_response(message, qa_pipeline=None, text_generator=None):
"""์ฑ—๋ด‡ ์‘๋‹ต ์ƒ์„ฑ"""
message_lower = message.lower()
# ์ธ์‚ฌ๋ง ์ฒ˜๋ฆฌ
if any(greeting in message_lower for greeting in ['์•ˆ๋…•', 'ํ•˜์ด', 'ํ—ฌ๋กœ', '๋ฐ˜๊ฐ€']):
return random.choice(CHATBOT_RESPONSES["greetings"])
# ๋ฐˆ ๊ด€๋ จ ์งˆ๋ฌธ ์ฒ˜๋ฆฌ
if any(word in message_lower for word in ['๋ฐˆ', 'meme', '์ด๋ฏธ์ง€', '์ƒ์„ฑ']):
return random.choice(CHATBOT_RESPONSES["meme_help"])
# AI ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•œ ์‘๋‹ต ์ƒ์„ฑ ์‹œ๋„
if qa_pipeline and len(message) > 10:
try:
# ๊ฐ„๋‹จํ•œ ์ปจํ…์ŠคํŠธ๋กœ QA ์ˆ˜ํ–‰
context = "์ด๊ฒƒ์€ ๋ฐˆ ์ƒ์„ฑ๊ณผ AI ์ฑ„ํŒ… ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋“ค์ด ์žฌ๋ฏธ์žˆ๋Š” ๋ฐˆ์„ ๋งŒ๋“ค๊ณ  AI์™€ ๋Œ€ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค."
result = qa_pipeline(question=message, context=context)
if result and 'answer' in result:
return f"๐Ÿค– {result['answer']}"
except Exception as e:
print(f"QA ํŒŒ์ดํ”„๋ผ์ธ ์˜ค๋ฅ˜: {e}")
# ํ…์ŠคํŠธ ์ƒ์„ฑ ๋ชจ๋ธ ์‚ฌ์šฉ ์‹œ๋„
if text_generator:
try:
result = text_generator(f"์‚ฌ์šฉ์ž: {message}\n๋ด‡:", max_length=50, num_return_sequences=1)
if result and len(result) > 0:
generated_text = result[0]['generated_text']
bot_response = generated_text.split('๋ด‡:')[-1].strip()
if bot_response and len(bot_response) > 5:
return f"๐Ÿค– {bot_response}"
except Exception as e:
print(f"ํ…์ŠคํŠธ ์ƒ์„ฑ ์˜ค๋ฅ˜: {e}")
# ๊ธฐ๋ณธ ์‘๋‹ต
return random.choice(CHATBOT_RESPONSES["default"])
def validate_input(text, max_length=100):
"""์ž…๋ ฅ ํ…์ŠคํŠธ ๊ฒ€์ฆ"""
if not text or not text.strip():
return False, "ํ…์ŠคํŠธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”."
if len(text) > max_length:
return False, f"ํ…์ŠคํŠธ๊ฐ€ ๋„ˆ๋ฌด ๊น๋‹ˆ๋‹ค. {max_length}์ž ์ดํ•˜๋กœ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”."
# ํŠน์ˆ˜๋ฌธ์ž ํ•„ํ„ฐ๋ง (์„ ํƒ์ )
forbidden_chars = ['<', '>', '&', '"', "'"]
if any(char in text for char in forbidden_chars):
return False, "ํ—ˆ์šฉ๋˜์ง€ ์•Š๋Š” ํŠน์ˆ˜๋ฌธ์ž๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค."
return True, "๊ฒ€์ฆ ํ†ต๊ณผ"
def get_random_meme_idea():
"""๋žœ๋ค ๋ฐˆ ์•„์ด๋””์–ด ์ œ๊ณต"""
ideas = [
("When you finish your project", "But remember you didn't write tests"),
("Me: I'll go to bed early tonight", "Also me at 3 AM:"),
("CSS in theory", "CSS in practice"),
("My code works", "I have no idea why"),
("Expected behavior", "Actual behavior")
]
return random.choice(ideas)
def format_trend_data(keyword, data=None):
"""ํŠธ๋ Œ๋“œ ๋ฐ์ดํ„ฐ ํฌ๋งทํŒ…"""
if not data:
# ์‹œ๋ฎฌ๋ ˆ์ด์…˜ ๋ฐ์ดํ„ฐ ์ƒ์„ฑ
popularity = random.randint(60, 95)
growth = random.randint(-20, 50)
related_terms = random.sample([
'๋ฐ”์ด๋Ÿด', '์ธ๊ธฐ', 'ํŠธ๋ Œ๋“œ', '์›ƒ๊ธด', '์žฌ๋ฏธ์žˆ๋Š”',
'ํ•ซ์ด์Šˆ', 'ํ™”์ œ', '๋ฐˆ', 'ํŒจ๋Ÿฌ๋””', '์œ ๋จธ'
], 3)
result = f"""
๐Ÿ“Š '{keyword}' ํŠธ๋ Œ๋“œ ๋ถ„์„ ๊ฒฐ๊ณผ
๐Ÿ”ฅ ์ธ๊ธฐ๋„: {popularity}/100
๐Ÿ“ˆ ์„ฑ์žฅ๋ฅ : {growth:+d}%
๐Ÿท๏ธ ๊ด€๋ จ ํ‚ค์›Œ๋“œ: {', '.join(related_terms)}
โฐ ๋ถ„์„ ์‹œ๊ฐ„: ๋ฐฉ๊ธˆ ์ „
๐Ÿ’ก ์ถ”์ฒœ: {'์ƒ์Šน ํŠธ๋ Œ๋“œ์ž…๋‹ˆ๋‹ค!' if growth > 0 else '๊ด€์‹ฌ์„ ๋Œ ์ˆ˜ ์žˆ๋Š” ํ‚ค์›Œ๋“œ์ž…๋‹ˆ๋‹ค.'}
"""
return result.strip()
return str(data)