import gradio as gr from datetime import datetime import re def extract_month_from_period(period_text): """이벤트 기간에서 월 추출""" if not period_text or period_text.strip() == "": return None date_patterns = [ r'(\d{4})\.(\d{1,2})\.(\d{1,2})', r'(\d{1,2})\.(\d{1,2})', r'(\d{1,2})월', ] for pattern in date_patterns: matches = re.findall(pattern, period_text) if matches: if len(matches[0]) == 3: month = int(matches[0][1]) elif len(matches[0]) == 2: month = int(matches[0][0]) else: month = int(matches[0]) if 1 <= month <= 12: return f"{month}월" return None def analyze_concepts(month): """20-40대 여성 맞춤 월별 컨셉 분석""" monthly_data = { "1월": { "special_days": ["미니멀 챌린지", "새해 리셋", "플래너 스타트"], "trends": ["미니멀", "자기계발", "플래너", "정리정돈"], "colors": ["#FF6B6B", "#4ECDC4", "#45B7D1"], "mood": "희망적이고 새로운 시작", "female_appeal": ["미니멀", "자기계발", "셀프케어"] }, "2월": { "special_days": ["갈렌타인데이", "셀프러브", "사랑의 달"], "trends": ["셀프러브", "갈렌타인", "로맨스", "따뜻한 감성"], "colors": ["#FF69B4", "#FFB6C1", "#DC143C"], "mood": "로맨틱하고 감성적", "female_appeal": ["셀프러브", "우정", "로맨스"] }, "3월": { "special_days": ["여성의 날", "봄의 시작", "새학기"], "trends": ["봄맞이", "벚꽃 시즌", "봄 패션", "새출발"], "colors": ["#FFB6C1", "#98FB98", "#87CEEB"], "mood": "설렘가득하고 활기찬", "female_appeal": ["봄 패션", "꽃구경", "새출발"] }, "4월": { "special_days": ["벚꽃 시즌", "봄나들이", "피크닉"], "trends": ["벚꽃축제", "봄피크닉", "아웃도어", "꽃놀이"], "colors": ["#98FB98", "#F0E68C", "#DDA0DD"], "mood": "생기발랄하고 즐거운", "female_appeal": ["벚꽃놀이", "피크닉", "봄여행"] }, "5월": { "special_days": ["로즈데이", "감사의 달", "힐링"], "trends": ["감사", "나들이", "로즈데이", "봄여행"], "colors": ["#32CD32", "#FFB6C1", "#87CEEB"], "mood": "따뜻하고 감사한", "female_appeal": ["로즈데이", "감사표현", "힐링"] }, "6월": { "special_days": ["키스데이", "여름 준비", "쿨링"], "trends": ["여름준비", "쿨링", "바캉스준비", "여름패션"], "colors": ["#00CED1", "#FFD700", "#FF6347"], "mood": "시원하고 활동적인", "female_appeal": ["여름준비", "쿨링케어", "바캉스"] }, "7월": { "special_days": ["실버데이", "여름휴가", "바캉스"], "trends": ["여름휴가", "바캉스", "휴가패션", "여행"], "colors": ["#00BFFF", "#FFD700", "#FF6347"], "mood": "역동적이고 자유로운", "female_appeal": ["바캉스", "여행", "휴가패션"] }, "8월": { "special_days": ["그린데이", "여름 마무리", "휴가"], "trends": ["여름휴가", "바다여행", "축제", "여름추억"], "colors": ["#00BFFF", "#FF6347", "#FFD700"], "mood": "열정적이고 추억가득한", "female_appeal": ["여름추억", "힐링", "여행"] }, "9월": { "special_days": ["포토데이", "뮤직데이", "가을시작"], "trends": ["가을패션", "독서", "문화생활", "감성"], "colors": ["#FF8C00", "#DC143C", "#B8860B"], "mood": "감성적이고 성숙한", "female_appeal": ["가을패션", "카페", "독서"] }, "10월": { "special_days": ["와인데이", "커피데이", "독서의 달"], "trends": ["가을단풍", "독서", "카페문화", "와인"], "colors": ["#FF8C00", "#DC143C", "#B8860B"], "mood": "감성적이고 여유로운", "female_appeal": ["단풍구경", "카페", "와인"] }, "11월": { "special_days": ["무비데이", "오렌지데이", "연말준비"], "trends": ["빼빼로데이", "연말준비", "겨울패션", "따뜻함"], "colors": ["#8B4513", "#A0522D", "#CD853F"], "mood": "포근하고 준비하는", "female_appeal": ["빼빼로데이", "겨울패션", "연말모임"] }, "12월": { "special_days": ["허그데이", "연말파티", "송년"], "trends": ["크리스마스", "연말파티", "선물", "송년회"], "colors": ["#DC143C", "#228B22", "#FFD700"], "mood": "축제같고 따뜻한", "female_appeal": ["크리스마스", "연말모임", "선물"] } } data = monthly_data.get(month, {}) concepts = [] # 컨셉 1 if data.get("special_days"): special = data["special_days"][0] concepts.append({ "name": f"{special} 이벤트", "theme": f"{special}를 테마로 한 여성 맞춤 이벤트", "score": 8.8, "reason": f"20-40대 여성이 공감할 수 있는 {special} 테마", "target": "20-40대 여성", "colors": data.get("colors", ["#FF69B4"]), "keywords": [special] + data.get("female_appeal", [])[:2], "is_recommended": True }) # 컨셉 2 if data.get("trends"): trend = data["trends"][0] concepts.append({ "name": f"{trend} 챌린지", "theme": f"{trend} 트렌드 참여형 이벤트", "score": 8.0, "reason": f"인기 {trend} 트렌드로 높은 관심도", "target": "20-30대 트렌드 민감층", "colors": data.get("colors", ["#4ECDC4"]), "keywords": data.get("trends", [])[:3], "is_recommended": False }) # 컨셉 3 concepts.append({ "name": f"{month} 셀프케어 위크", "theme": "나를 위한 특별한 시간", "score": 8.3, "reason": "셀프케어로 강한 어필", "target": "20-40대 여성", "colors": data.get("colors", ["#FFB6C1"]), "keywords": ["셀프케어", "힐링", "나를 위한 시간"], "is_recommended": True }) concepts.sort(key=lambda x: (x.get("is_recommended", False), x["score"]), reverse=True) recommended_concept = next((c for c in concepts if c.get("is_recommended", False)), concepts[0]) result = f"# 🎯 {month} 20-40대 여성 맞춤 컨셉 분석\n\n" result += f"## 🏆 이달의 추천 컨셉: {recommended_concept['name']}\n" result += f"**⭐ 추천 이유:** {recommended_concept['reason']}\n" result += f"**📊 예상 참여도:** {recommended_concept['score']}/10점\n\n" result += "---\n\n" concept_names = [] for i, concept in enumerate(concepts, 1): is_recommended_mark = " 🏆 **추천**" if concept.get("is_recommended", False) else "" result += f"## {i}. {concept['name']}{is_recommended_mark}\n" result += f"**🏷️ 테마:** {concept['theme']}\n" result += f"**⭐ 참여도 점수:** {concept['score']}/10점\n" result += f"**💡 선정 이유:** {concept['reason']}\n" result += f"**🎯 주요 타겟:** {concept['target']}\n" result += f"**🔑 핵심 키워드:** {', '.join(concept['keywords'])}\n" result += f"**🎨 추천 색상:** {', '.join(concept['colors'])}\n\n" result += "---\n\n" concept_names.append(concept['name']) return result, concept_names def generate_design_recommendations(concept_name, month): """디자인 추천""" design_styles = { "미니멀": ["심플 미니멀 디자인", "깔끔한 선과 여백을 활용"], "네온사인": ["레트로 네온사인 스타일", "80년대 네온사인 화려함"], "Y2K": ["Y2K 레트로 퓨처", "2000년대 미래적 감성"], "게임UI": ["게임 인터페이스", "RPG 게임 UI 모티브"] } monthly_design = { "1월": ["미니멀", "Y2K"], "2월": ["미니멀", "네온사인"], "3월": ["네온사인", "Y2K"], "4월": ["네온사인", "Y2K"], "5월": ["미니멀", "네온사인"], "6월": ["네온사인", "Y2K"], "7월": ["Y2K", "네온사인"], "8월": ["Y2K", "게임UI"], "9월": ["미니멀", "네온사인"], "10월": ["미니멀", "네온사인"], "11월": ["미니멀", "네온사인"], "12월": ["네온사인", "게임UI"] } month_key = month.replace('월', '월') recommended_designs = monthly_design.get(month_key, ["미니멀", "네온사인"]) result = "## 🎨 추천 디자인 스타일\n\n" for i, design_key in enumerate(recommended_designs, 1): if design_key in design_styles: style_name, description = design_styles[design_key] result += f"### {i}. {style_name} 🌟\n" result += f"**설명:** {description}\n\n" return result def generate_trendy_copy(concept_name, month): """트렌디한 카피라이팅 생성""" trendy_copies = { "미니멀": { "sub1": "🌟 '나는 정리를 못하는 여자'는 이제 그만!", "main": "미니멀은 '미'니로 '말'하는 거야, 작게 말해도 큰 변화! ✨", "sub2": "올해는 진짜 '갓생'을 살아보자구요! 💪", "hashtags": ["#갓생살기", "#미니멀", "#정리의신", "#새해정리"] }, "그린데이": { "sub1": "💚 '그린'하면 생각나는 게 뭐예요?", "main": "그린데이는 '그'냥 '린'스하지 말고 새롭게! 💚", "sub2": "이번 여름엔 '그린'한 추억 만들어요 🌿", "hashtags": ["#그린데이", "#여름추억", "#힐링", "#자연"] }, "셀프케어": { "sub1": "💕 '나 자신과 연애 중'이라고 말할 수 있나요?", "main": "셀프케어는 '셀프'로 '케어'하는 거 맞아! 💖", "sub2": "오늘부터 내가 내 최고의 친구가 되는 거야 ✨", "hashtags": ["#셀프케어", "#나를위한시간", "#힐링", "#자기사랑"] } } # 기본 카피 default_copy = { "sub1": "✨ 이런 특별한 순간을 놓칠 수 없죠!", "main": "지금 이 순간이 바로 '찐'이야! 💫", "sub2": "함께라면 뭐든 '레전드'가 될 수 있어요 🎉", "hashtags": ["#찐이야", "#레전드순간", "#함께해요", "#특별한시간"] } # 컨셉명에서 키워드 찾기 for keyword, copy_data in trendy_copies.items(): if keyword in concept_name: return copy_data return default_copy def generate_notice(concept, event_type, event_period, prize_benefits): """공지사항 생성""" if not concept: return "먼저 컨셉을 선택해주세요." # 이벤트 기간 설정 if not event_period or event_period.strip() == "": now = datetime.now() start_date = now.strftime("%Y.%m.%d") end_date = f"{now.year}.{now.month}.{now.day + 7}" period_text = f"{start_date} ~ {end_date}" else: period_text = event_period # 월 추출 month = extract_month_from_period(period_text) if not month: month = f"{datetime.now().month}월" # 카피 생성 copy_data = generate_trendy_copy(concept, month) # 디자인 추천 design_recommendations = generate_design_recommendations(concept, month) # 당첨 혜택 설정 if not prize_benefits or prize_benefits.strip() == "": benefits_text = """✨ 1등 (1명): 스타벅스 5만원 기프트카드 🎉 2등 (3명): 베스킨라빈스 아이스크림 쿠폰 💝 3등 (10명): 편의점 5천원 상품권 🌟 참가상 (50명): 모바일 치킨 쿠폰""" else: benefits_text = prize_benefits # 해시태그 hashtags_text = " ".join(copy_data['hashtags']) notice = f"""{copy_data['sub1']} 💫 {copy_data['main']} 💫 {copy_data['sub2']} 🎉 {concept} 🎉 📅 이벤트 기간: {period_text} 23:59 {hashtags_text} {design_recommendations} ======================== ✨ EVENT 특별한 {concept}을 준비했어요! 많은 분들의 적극적인 참여를 기다리고 있습니다 💕 이번 이벤트는 단순한 참여가 아닌, 우리만의 특별한 추억을 만들어가는 시간이에요 ✨ ======================== 🎯 참여 방법 1️⃣ 이벤트 내용 확인하기 2️⃣ {event_type} 참여하기 3️⃣ 참여 완료! ================= 🎁 당첨혜택 {benefits_text} 📋 추첨: 참여자 중 무작위 추첨 ======================== 👥 이벤트 대상 ✅ 커뮤니티 회원 ✅ 만 18세 이상 ✅ 이벤트 기간 내 참여자 ======================== ⚠️ 주의사항 ※ 부적절한 참여는 제외됩니다 ※ 중복 참여 불가 ※ 당첨자는 본인 확인 필요 =========================== 📞 문의: 1234-5678 💬 카카오톡: @event_community {hashtags_text} 💝 많은 참여 부탁드려요! 감사합니다 💝""" return notice def create_interface(): """그라디오 인터페이스 생성""" with gr.Blocks(title="이벤트 공지사항 생성기") as demo: gr.Markdown("# 🎉 이벤트 공지사항 생성기") gr.Markdown("### 20-40대 여성 맞춤 트렌디한 이벤트를 만들어보세요!") with gr.Row(): with gr.Column(): gr.Markdown("## 설정") event_period_input = gr.Textbox( label="이벤트 기간", placeholder="예: 2025.8.1 ~ 2025.8.10", info="이벤트 기간을 입력하면 해당 월이 자동으로 선택됩니다" ) month_dropdown = gr.Dropdown( choices=[f"{i}월" for i in range(1, 13)], label="이벤트 월 선택", value="1월" ) analyze_btn = gr.Button("컨셉 분석하기", variant="primary") concept_dropdown = gr.Dropdown( label="컨셉 선택", visible=False ) event_type_dropdown = gr.Dropdown( choices=["댓글 달기", "게시글 작성", "좋아요 누르기"], label="이벤트 유형", value="댓글 달기" ) gr.Markdown("## 🎁 당첨 혜택 설정") prize_benefits_input = gr.Textbox( label="당첨 혜택", placeholder="당첨 혜택을 입력하세요 (비워두면 기본 혜택 적용)", lines=6 ) generate_btn = gr.Button("공지사항 생성하기", variant="secondary", visible=False) with gr.Column(): gr.Markdown("## 결과") concept_output = gr.Textbox( label="컨셉 분석 결과", lines=20, placeholder="먼저 '컨셉 분석하기' 버튼을 클릭하세요" ) notice_output = gr.Textbox( label="생성된 공지사항", lines=25, placeholder="컨셉을 선택하고 '공지사항 생성하기' 버튼을 클릭하세요" ) # 상태 변수 concepts_state = gr.State([]) selected_concept_state = gr.State("") def handle_period_change(period_text): detected_month = extract_month_from_period(period_text) if detected_month: return gr.update(value=detected_month) return gr.update() def handle_analyze(month): result, concepts = analyze_concepts(month) return ( result, gr.update(choices=concepts, visible=True, value=concepts[0]), gr.update(visible=True), concepts ) def handle_concept_change(concept, concepts): return concept def handle_generate(concept, event_type, event_period, prize_benefits): notice = generate_notice(concept, event_type, event_period, prize_benefits) return notice # 이벤트 연결 event_period_input.change( handle_period_change, inputs=[event_period_input], outputs=[month_dropdown] ) analyze_btn.click( handle_analyze, inputs=[month_dropdown], outputs=[concept_output, concept_dropdown, generate_btn, concepts_state] ) concept_dropdown.change( handle_concept_change, inputs=[concept_dropdown, concepts_state], outputs=[selected_concept_state] ) generate_btn.click( handle_generate, inputs=[selected_concept_state, event_type_dropdown, event_period_input, prize_benefits_input], outputs=[notice_output] ) return demo if __name__ == "__main__": demo = create_interface() demo.launch()