""" SNS 콘텐츠 생성 서비스 """ import os from typing import Dict, Any from datetime import datetime from utils.ai_client import AIClient from utils.image_processor import ImageProcessor from models.request_models import SnsContentGetRequest class SnsContentService: def __init__(self): """서비스 초기화""" self.ai_client = AIClient() self.image_processor = ImageProcessor() # 플랫폼별 콘텐츠 특성 정의 self.platform_specs = { '인스타그램': { 'max_length': 2200, 'hashtag_count': 15, 'style': '감성적이고 시각적', 'format': '짧은 문장, 해시태그 활용' }, '네이버 블로그': { 'max_length': 3000, 'hashtag_count': 10, 'style': '정보성과 친근함', 'format': '구조화된 내용, 상세 설명' } } # 톤앤매너별 스타일 self.tone_styles = { '친근한': '반말, 이모티콘 활용, 편안한 어조', '정중한': '존댓말, 격식 있는 표현, 신뢰감 있는 어조', '재미있는': '유머 섞인 표현, 트렌디한 말투, 참신한 비유', '전문적인': '전문 용어 활용, 체계적 설명, 신뢰성 강조' } # 감정 강도별 표현 self.emotion_levels = { '약함': '은은하고 차분한 표현', '보통': '적당히 활기찬 표현', '강함': '매우 열정적이고 강렬한 표현' } def generate_sns_content(self, request: SnsContentGetRequest) -> Dict[str, Any]: """ SNS 콘텐츠 생성 (HTML 형식 반환) """ try: # 이미지 다운로드 및 분석 image_analysis = self._analyze_images_from_urls(request.images) # AI 프롬프트 생성 prompt = self._create_sns_prompt(request, image_analysis) # AI로 콘텐츠 생성 generated_content = self.ai_client.generate_text(prompt) # HTML 형식으로 포맷팅 html_content = self._format_to_html(generated_content, request) return { 'success': True, 'content': html_content } except Exception as e: return { 'success': False, 'error': str(e) } def _analyze_images_from_urls(self, image_urls: list) -> Dict[str, Any]: """ URL에서 이미지를 다운로드하고 분석 """ analysis_results = [] temp_files = [] try: for image_url in image_urls: # 이미지 다운로드 temp_path = self.ai_client.download_image_from_url(image_url) if temp_path: temp_files.append(temp_path) # 이미지 분석 try: image_info = self.image_processor.get_image_info(temp_path) image_description = self.ai_client.analyze_image(temp_path) analysis_results.append({ 'url': image_url, 'info': image_info, 'description': image_description }) except Exception as e: analysis_results.append({ 'url': image_url, 'error': str(e) }) return { 'total_images': len(image_urls), 'results': analysis_results } finally: # 임시 파일 정리 for temp_file in temp_files: try: os.remove(temp_file) except: pass def _create_sns_prompt(self, request: SnsContentGetRequest, image_analysis: Dict[str, Any]) -> str: """ SNS 콘텐츠 생성을 위한 AI 프롬프트 생성 """ platform_spec = self.platform_specs.get(request.platform, self.platform_specs['인스타그램']) tone_style = self.tone_styles.get(request.toneAndManner, '친근한 어조') emotion_level = self.emotion_levels.get(request.emotionIntensity, '적당한 강도') # 이미지 설명 추출 image_descriptions = [] for result in image_analysis.get('results', []): if 'description' in result: image_descriptions.append(result['description']) prompt = f""" 당신은 소상공인을 위한 SNS 마케팅 콘텐츠 전문가입니다. 다음 정보를 바탕으로 {request.platform}에 적합한 게시글을 작성해주세요. **게시물 정보:** - 제목: {request.title} - 카테고리: {request.category} - 콘텐츠 타입: {request.contentType} **스타일 요구사항:** - 톤앤매너: {request.toneAndManner} ({tone_style}) - 감정 강도: {request.emotionIntensity} ({emotion_level}) - 특별 요구사항: {request.requirement or '없음'} **이벤트 정보:** - 이벤트명: {request.eventName or '없음'} - 시작일: {request.startDate or '없음'} - 종료일: {request.endDate or '없음'} **이미지 분석 결과:** {chr(10).join(image_descriptions) if image_descriptions else '이미지 없음'} **플랫폼 특성:** - 최대 길이: {platform_spec['max_length']}자 - 스타일: {platform_spec['style']} - 형식: {platform_spec['format']} **요구사항:** 1. {request.platform}의 특성에 맞는 톤앤매너 사용 2. {request.category} 카테고리에 적합한 내용 구성 3. 고객의 관심을 끌 수 있는 매력적인 문구 사용 4. 이미지와 연관된 내용으로 작성 5. 지정된 톤앤매너와 감정 강도에 맞게 작성 본문과 해시태그를 모두 포함하여 완성된 게시글을 작성해주세요. """ return prompt def _format_to_html(self, content: str, request: SnsContentGetRequest) -> str: """ 생성된 콘텐츠를 HTML 형식으로 포맷팅 """ # 줄바꿈을
태그로 변환 content = content.replace('\n', '
') # 해시태그를 파란색으로 스타일링 import re content = re.sub(r'(#[\w가-힣]+)', r'\1', content) # 이모티콘은 그대로 유지 # 전체 HTML 구조 html_content = f"""

{request.platform} 게시물

{content}
{self._add_metadata_html(request)}
""" return html_content def _add_metadata_html(self, request: SnsContentGetRequest) -> str: """ 메타데이터를 HTML에 추가 """ metadata_html = '
' if request.eventName: metadata_html += f'
이벤트: {request.eventName}
' if request.startDate and request.endDate: metadata_html += f'
기간: {request.startDate} ~ {request.endDate}
' metadata_html += f'
카테고리: {request.category}
' metadata_html += f'
생성일: {datetime.now().strftime("%Y-%m-%d %H:%M")}
' metadata_html += '
' return metadata_html