Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -7,21 +7,20 @@ def extract_month_from_period(period_text):
|
|
7 |
if not period_text or period_text.strip() == "":
|
8 |
return None
|
9 |
|
10 |
-
# 날짜 패턴 찾기 (YYYY.MM.DD 또는 MM.DD 형식)
|
11 |
date_patterns = [
|
12 |
-
r'(\d{4})\.(\d{1,2})\.(\d{1,2})',
|
13 |
-
r'(\d{1,2})\.(\d{1,2})',
|
14 |
-
r'(\d{1,2})월',
|
15 |
]
|
16 |
|
17 |
for pattern in date_patterns:
|
18 |
matches = re.findall(pattern, period_text)
|
19 |
if matches:
|
20 |
-
if len(matches[0]) == 3:
|
21 |
month = int(matches[0][1])
|
22 |
-
elif len(matches[0]) == 2:
|
23 |
month = int(matches[0][0])
|
24 |
-
else:
|
25 |
month = int(matches[0])
|
26 |
|
27 |
if 1 <= month <= 12:
|
@@ -32,239 +31,147 @@ def extract_month_from_period(period_text):
|
|
32 |
def analyze_concepts(month):
|
33 |
"""20-40대 여성 맞춤 월별 컨셉 분석"""
|
34 |
|
35 |
-
# 월별 상세 데이터 (20-40대 여성 타겟 특화)
|
36 |
monthly_data = {
|
37 |
"1월": {
|
38 |
-
"holidays": ["신정", "설날"],
|
39 |
"special_days": ["미니멀 챌린지", "새해 리셋", "플래너 스타트"],
|
40 |
-
"
|
41 |
-
"trends": ["미니멀", "자기계발", "플래너", "정리정돈", "헬스케어", "독서"],
|
42 |
-
"seasons": ["겨울", "신년", "새로운 시작"],
|
43 |
"colors": ["#FF6B6B", "#4ECDC4", "#45B7D1"],
|
44 |
"mood": "희망적이고 새로운 시작",
|
45 |
-
"female_appeal": ["미니멀", "자기계발", "셀프케어"
|
46 |
},
|
47 |
"2월": {
|
48 |
-
"holidays": ["밸런타인데이"],
|
49 |
"special_days": ["갈렌타인데이", "셀프러브", "사랑의 달"],
|
50 |
-
"
|
51 |
-
"trends": ["셀프러브", "갈렌타인", "로맨스", "따뜻한 감성", "핑크 무드"],
|
52 |
-
"seasons": ["겨울 끝", "봄 준비", "로맨틱"],
|
53 |
"colors": ["#FF69B4", "#FFB6C1", "#DC143C"],
|
54 |
"mood": "로맨틱하고 감성적",
|
55 |
-
"female_appeal": ["셀프러브", "우정", "로맨스"
|
56 |
},
|
57 |
"3월": {
|
58 |
-
"holidays": ["삼일절", "화이트데이"],
|
59 |
"special_days": ["여성의 날", "봄의 시작", "새학기"],
|
60 |
-
"
|
61 |
-
"trends": ["봄맞이", "벚꽃 시즌", "봄 패션", "새출발", "꽃구경"],
|
62 |
-
"seasons": ["봄", "벚꽃", "새싹"],
|
63 |
"colors": ["#FFB6C1", "#98FB98", "#87CEEB"],
|
64 |
"mood": "설렘가득하고 활기찬",
|
65 |
-
"female_appeal": ["봄 패션", "꽃구경", "새출발"
|
66 |
},
|
67 |
"4월": {
|
68 |
-
"holidays": ["만우절"],
|
69 |
"special_days": ["벚꽃 시즌", "봄나들이", "피크닉"],
|
70 |
-
"
|
71 |
-
"trends": ["벚꽃축제", "봄피크닉", "아웃도어", "꽃놀이", "봄여행"],
|
72 |
-
"seasons": ["봄 절정", "꽃구경", "나들이"],
|
73 |
"colors": ["#98FB98", "#F0E68C", "#DDA0DD"],
|
74 |
"mood": "생기발랄하고 즐거운",
|
75 |
-
"female_appeal": ["벚꽃놀이", "피크닉", "봄여행"
|
76 |
},
|
77 |
"5월": {
|
78 |
-
"
|
79 |
-
"
|
80 |
-
"seasonal_terms": ["입하", "소만"],
|
81 |
-
"trends": ["감사", "나들이", "로즈데이", "봄여행", "힐링"],
|
82 |
-
"seasons": ["신록", "야외활동", "따뜻함"],
|
83 |
"colors": ["#32CD32", "#FFB6C1", "#87CEEB"],
|
84 |
"mood": "따뜻하고 감사한",
|
85 |
-
"female_appeal": ["로즈데이", "감사표현", "힐링"
|
86 |
},
|
87 |
"6월": {
|
88 |
-
"
|
89 |
-
"
|
90 |
-
"seasonal_terms": ["망종", "하지"],
|
91 |
-
"trends": ["여름준비", "다이어트", "쿨링", "바캉스준비", "여름패션"],
|
92 |
-
"seasons": ["초여름", "더위", "여름준비"],
|
93 |
"colors": ["#00CED1", "#FFD700", "#FF6347"],
|
94 |
"mood": "시원하고 활동적인",
|
95 |
-
"female_appeal": ["
|
96 |
},
|
97 |
"7월": {
|
98 |
-
"holidays": ["제헌절"],
|
99 |
"special_days": ["실버데이", "여름휴가", "바캉스"],
|
100 |
-
"
|
101 |
-
"trends": ["여름휴가", "바캉스", "휴가패션", "여행", "힐링"],
|
102 |
-
"seasons": ["여름", "휴가", "바캉스"],
|
103 |
"colors": ["#00BFFF", "#FFD700", "#FF6347"],
|
104 |
"mood": "역동적이고 자유로운",
|
105 |
-
"female_appeal": ["바캉스", "여행", "휴가패션"
|
106 |
},
|
107 |
"8월": {
|
108 |
-
"holidays": ["광복절"],
|
109 |
"special_days": ["그린데이", "여름 마무리", "휴가"],
|
110 |
-
"
|
111 |
-
"trends": ["여름휴가", "바다여행", "축제", "여름추억", "힐링"],
|
112 |
-
"seasons": ["한여름", "휴가절정", "추억"],
|
113 |
"colors": ["#00BFFF", "#FF6347", "#FFD700"],
|
114 |
"mood": "열정적이고 추억가득한",
|
115 |
-
"female_appeal": ["여름추억", "힐링", "여행"
|
116 |
},
|
117 |
"9월": {
|
118 |
-
"holidays": ["추석"],
|
119 |
"special_days": ["포토데이", "뮤직데이", "가을시작"],
|
120 |
-
"
|
121 |
-
"trends": ["가을패션", "독서", "문화생활", "감성", "카페"],
|
122 |
-
"seasons": ["가을", "선선함", "감성"],
|
123 |
"colors": ["#FF8C00", "#DC143C", "#B8860B"],
|
124 |
"mood": "감성적이고 성숙한",
|
125 |
-
"female_appeal": ["가을패션", "카페", "독서"
|
126 |
},
|
127 |
"10월": {
|
128 |
-
"holidays": ["한글날"],
|
129 |
"special_days": ["와인데이", "커피데이", "독서의 달"],
|
130 |
-
"
|
131 |
-
"trends": ["가을단풍", "독서", "카페문화", "와인", "감성"],
|
132 |
-
"seasons": ["단풍", "가을정취", "감성"],
|
133 |
"colors": ["#FF8C00", "#DC143C", "#B8860B"],
|
134 |
"mood": "감성적이고 여유로운",
|
135 |
-
"female_appeal": ["단풍구경", "카페", "와인"
|
136 |
},
|
137 |
"11월": {
|
138 |
-
"holidays": ["빼빼로데이"],
|
139 |
"special_days": ["무비데이", "오렌지데이", "연말준비"],
|
140 |
-
"
|
141 |
-
"trends": ["빼빼로데이", "연말준비", "겨울패션", "따뜻함", "코지"],
|
142 |
-
"seasons": ["늦가을", "겨울준비", "포근함"],
|
143 |
"colors": ["#8B4513", "#A0522D", "#CD853F"],
|
144 |
"mood": "포근하고 준비하는",
|
145 |
-
"female_appeal": ["빼빼로데이", "겨울패션", "연말모임"
|
146 |
},
|
147 |
"12월": {
|
148 |
-
"holidays": ["크리스마스"],
|
149 |
"special_days": ["허그데이", "연말파티", "송년"],
|
150 |
-
"
|
151 |
-
"trends": ["크리스마스", "연말파티", "선물", "송년회", "겨울감성"],
|
152 |
-
"seasons": ["겨울", "연말", "크리스마스"],
|
153 |
"colors": ["#DC143C", "#228B22", "#FFD700"],
|
154 |
"mood": "축제같고 따뜻한",
|
155 |
-
"female_appeal": ["크리스마스", "연말모임", "선물"
|
156 |
}
|
157 |
}
|
158 |
|
159 |
data = monthly_data.get(month, {})
|
160 |
|
161 |
-
# 20-40대 여성 맞춤 컨셉 생성 (6가지)
|
162 |
concepts = []
|
163 |
|
164 |
-
# 컨셉 1
|
165 |
if data.get("special_days"):
|
166 |
special = data["special_days"][0]
|
167 |
concepts.append({
|
168 |
"name": f"{special} 이벤트",
|
169 |
-
"theme": f"{special}를 테마로 한
|
170 |
"score": 8.8,
|
171 |
-
"reason": f"20-40대 여성이 공감할 수 있는 {special}
|
172 |
-
"target": "20-40대
|
173 |
"colors": data.get("colors", ["#FF69B4"]),
|
174 |
"keywords": [special] + data.get("female_appeal", [])[:2],
|
175 |
-
"participation_factor": "여성층 공감대, 특별함",
|
176 |
"is_recommended": True
|
177 |
})
|
178 |
|
179 |
-
# 컨셉 2
|
180 |
if data.get("trends"):
|
181 |
trend = data["trends"][0]
|
182 |
concepts.append({
|
183 |
"name": f"{trend} 챌린지",
|
184 |
-
"theme": f"
|
185 |
-
"score": 8.
|
186 |
-
"reason": f"
|
187 |
-
"target": "20-30대 트렌드
|
188 |
"colors": data.get("colors", ["#4ECDC4"]),
|
189 |
"keywords": data.get("trends", [])[:3],
|
190 |
-
"participation_factor": "트렌드 화제성, SNS 확산성",
|
191 |
-
"is_recommended": False
|
192 |
-
})
|
193 |
-
|
194 |
-
# 컨셉 3: 절기 기반 (현대적 해석)
|
195 |
-
if data.get("seasonal_terms"):
|
196 |
-
term = data["seasonal_terms"][0]
|
197 |
-
concepts.append({
|
198 |
-
"name": f"{term} 모던 감성",
|
199 |
-
"theme": f"절기 {term}을 현대적으로 해석한 감성 이벤트",
|
200 |
-
"score": 7.5,
|
201 |
-
"reason": f"전통 절기를 현대 여성 감성으로 재해석한 참신함",
|
202 |
-
"target": "전연령 여성, 감성적 취향층",
|
203 |
-
"colors": data.get("colors", ["#8FBC8F"]),
|
204 |
-
"keywords": data.get("seasonal_terms", [])[:2] + ["모던", "감성"],
|
205 |
-
"participation_factor": "전통의 현대적 재해석, 감성적 어필",
|
206 |
"is_recommended": False
|
207 |
})
|
208 |
|
209 |
-
# 컨셉
|
210 |
-
if data.get("seasons"):
|
211 |
-
season = data["seasons"][0]
|
212 |
-
concepts.append({
|
213 |
-
"name": f"{season} 감성 모먼트",
|
214 |
-
"theme": f"{season} 계절을 만끽하는 여성 감성 이벤트",
|
215 |
-
"score": 8.0,
|
216 |
-
"reason": f"{season} 계절감과 여성 감성을 결합한 자연스러운 참여 유도",
|
217 |
-
"target": "20-40대 감성 중시 여성, 계절감 추구층",
|
218 |
-
"colors": data.get("colors", ["#98FB98"]),
|
219 |
-
"keywords": data.get("seasons", []) + data.get("female_appeal", [])[:2],
|
220 |
-
"participation_factor": "계절 감성, 여성 공감대",
|
221 |
-
"is_recommended": True
|
222 |
-
})
|
223 |
-
|
224 |
-
# 컨셉 5: 셀프케어/힐링 기반
|
225 |
concepts.append({
|
226 |
"name": f"{month} 셀프케어 위크",
|
227 |
-
"theme": "나를 위한 특별한
|
228 |
"score": 8.3,
|
229 |
-
"reason": "
|
230 |
-
"target": "20-40대
|
231 |
"colors": data.get("colors", ["#FFB6C1"]),
|
232 |
-
"keywords": ["셀프케어", "힐링", "나를 위한 시간"
|
233 |
-
"participation_factor": "자기관리 욕구, 힐링 니즈",
|
234 |
"is_recommended": True
|
235 |
})
|
236 |
|
237 |
-
# 컨셉 6: 커뮤니티 소통 (여성 친화적)
|
238 |
-
concepts.append({
|
239 |
-
"name": f"{month} 언니들의 수다",
|
240 |
-
"theme": "20-40대 여성들의 진솔한 소통과 공감 이벤트",
|
241 |
-
"score": 7.8,
|
242 |
-
"reason": "여성 커뮤니티 특성을 살린 친밀한 소통으로 참여 유도",
|
243 |
-
"target": "기존 여성 회원, 커뮤니티 소통 선호층",
|
244 |
-
"colors": data.get("colors", ["#87CEEB"]),
|
245 |
-
"keywords": ["소통", "공감", "언니들", "진솔함"],
|
246 |
-
"participation_factor": "여성 커뮤니티 소속감, 친밀감",
|
247 |
-
"is_recommended": False
|
248 |
-
})
|
249 |
-
|
250 |
-
# 점수순 정렬 및 추천 컨셉 우선
|
251 |
concepts.sort(key=lambda x: (x.get("is_recommended", False), x["score"]), reverse=True)
|
252 |
|
253 |
-
# 추천 컨셉 찾기
|
254 |
recommended_concept = next((c for c in concepts if c.get("is_recommended", False)), concepts[0])
|
255 |
|
256 |
-
# 결과 텍스트 생성
|
257 |
result = f"# 🎯 {month} 20-40대 여성 맞춤 컨셉 분석\n\n"
|
258 |
result += f"## 🏆 이달의 추천 컨셉: {recommended_concept['name']}\n"
|
259 |
result += f"**⭐ 추천 이유:** {recommended_concept['reason']}\n"
|
260 |
result += f"**📊 예상 참여도:** {recommended_concept['score']}/10점\n\n"
|
261 |
result += "---\n\n"
|
262 |
|
263 |
-
result += f"**📊 분석 기준:** {data.get('mood', '특별한')} 분위기\n"
|
264 |
-
result += f"**🎨 주요 색상:** {', '.join(data.get('colors', ['기본색상'])[:3])}\n"
|
265 |
-
result += f"**🔥 여성 어필 트렌드:** {', '.join(data.get('female_appeal', ['기본트렌드'])[:3])}\n"
|
266 |
-
result += f"**🌿 해당 절기:** {', '.join(data.get('seasonal_terms', ['해당없음']))}\n\n"
|
267 |
-
|
268 |
concept_names = []
|
269 |
|
270 |
for i, concept in enumerate(concepts, 1):
|
@@ -275,148 +182,293 @@ def analyze_concepts(month):
|
|
275 |
result += f"**💡 선정 이유:** {concept['reason']}\n"
|
276 |
result += f"**🎯 주요 타겟:** {concept['target']}\n"
|
277 |
result += f"**🔑 핵심 키워드:** {', '.join(concept['keywords'])}\n"
|
278 |
-
result += f"**📈 참여 요인:** {concept['participation_factor']}\n"
|
279 |
result += f"**🎨 추천 색상:** {', '.join(concept['colors'])}\n\n"
|
280 |
result += "---\n\n"
|
281 |
|
282 |
concept_names.append(concept['name'])
|
283 |
|
284 |
-
result += f"**💬 총평:** {month}은 {data.get('mood', '특별한')} 특성을 가진 달로, "
|
285 |
-
result += f"특히 20-40대 여성에게는 '{data.get('female_appeal', ['특별한'])[0]}' 관련 이벤트가 "
|
286 |
-
result += f"높은 참여도를 보일 것으로 예상됩니다."
|
287 |
-
|
288 |
return result, concept_names
|
289 |
|
290 |
def generate_design_recommendations(concept_name, month):
|
291 |
-
"""
|
292 |
|
293 |
design_styles = {
|
294 |
-
"미니멀":
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
"colors": ["화이트", "베이지", "소프트 그레이"],
|
299 |
-
"elements": ["기하학적 도형", "타이포그래피 중심", "여백 활용"]
|
300 |
-
},
|
301 |
-
"네온사인": {
|
302 |
-
"style": "레트로 네온사인 스타일",
|
303 |
-
"description": "80년대 네온사인을 연상시키는 화려한 디자인",
|
304 |
-
"engagement": "강렬한 임팩트로 눈길 끌기 + 레트로 감성으로 MZ세대 어필",
|
305 |
-
"colors": ["네온 핑크", "사이버 블루", "일렉트릭 퍼플"],
|
306 |
-
"elements": ["글로우 이펙트", "그라데이션", "미래적 폰트"]
|
307 |
-
},
|
308 |
-
"손그림": {
|
309 |
-
"style": "손그림 일러스트 스타일",
|
310 |
-
"description": "따뜻하고 친근한 손그림 느낌의 일러스트",
|
311 |
-
"engagement": "친근함과 정성스러운 느낌으로 감정적 유대감 형성",
|
312 |
-
"colors": ["파스텔 톤", "자연색상", "부드러운 색감"],
|
313 |
-
"elements": ["손글씨 폰트", "낙서 느낌", "유기적 형태"]
|
314 |
-
},
|
315 |
-
"Y2K": {
|
316 |
-
"style": "Y2K 레트로 퓨처 스타일",
|
317 |
-
"description": "2000년대 초반 미래적 감성의 화려한 디자인",
|
318 |
-
"engagement": "노스탤지어 + 독특함으로 화제성 극대화",
|
319 |
-
"colors": ["홀로그램", "메탈릭", "그라데이션"],
|
320 |
-
"elements": ["3D 오브젝트", "크롬 효과", "기하학 패턴"]
|
321 |
-
},
|
322 |
-
"코어": {
|
323 |
-
"style": "○○코어 트렌드 스타일",
|
324 |
-
"description": "coquette, cottagecore 등 인스타 트렌드 반영",
|
325 |
-
"engagement": "인스타 감성으로 SNS 공유욕구 자극",
|
326 |
-
"colors": ["빈티지 톤", "무드 컬러", "감성 색상"],
|
327 |
-
"elements": ["빈티지 텍스처", "감성 오브젝트", "무드 사진"]
|
328 |
-
},
|
329 |
-
"게임UI": {
|
330 |
-
"style": "게임 인터페이스 스타일",
|
331 |
-
"description": "RPG나 모바일 게임의 UI를 모티브로 한 디자인",
|
332 |
-
"engagement": "게임화 요소로 참여 재미도 증가 + 젊은층 어필",
|
333 |
-
"colors": ["비비드 컬러", "골드 액센트", "다크 모드"],
|
334 |
-
"elements": ["체력바", "레벨업", "아이템 아이콘"]
|
335 |
-
}
|
336 |
}
|
337 |
|
338 |
-
# 월별 추천 디자인 (계절과 분위기에 맞게)
|
339 |
monthly_design = {
|
340 |
-
"1월": ["미니멀", "Y2K"], "2월": ["
|
341 |
-
"3월": ["
|
342 |
-
"5월": ["
|
343 |
"7월": ["Y2K", "네온사인"], "8월": ["Y2K", "게임UI"],
|
344 |
-
"9월": ["
|
345 |
-
"11월": ["미니멀", "
|
346 |
}
|
347 |
|
348 |
month_key = month.replace('월', '월')
|
349 |
-
recommended_designs = monthly_design.get(month_key, ["미니멀", "
|
350 |
|
351 |
result = "## 🎨 추천 디자인 스타일\n\n"
|
352 |
|
353 |
for i, design_key in enumerate(recommended_designs, 1):
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
result += f"**추천 색상:** {', '.join(design['colors'])}\n"
|
359 |
-
result += f"**핵심 요소:** {', '.join(design['elements'])}\n\n"
|
360 |
|
361 |
return result
|
362 |
|
363 |
-
def generate_trendy_copy(concept_name, month
|
364 |
-
"""
|
365 |
|
366 |
-
# 2024-2025 최신 트렌드 반영
|
367 |
trendy_copies = {
|
368 |
"미니멀": {
|
369 |
"sub1": "🌟 '나는 정리를 못하는 여자'는 이제 그만!",
|
370 |
"main": "미니멀은 '미'니로 '말'하는 거야, 작게 말해도 큰 변화! ✨",
|
371 |
"sub2": "올해는 진짜 '갓생'을 살아보자구요! 💪",
|
372 |
-
"hashtags": ["#갓생살기", "#미니멀", "#정리의신", "#새해정리"]
|
373 |
-
"reference": "정리의 신, 갓생 트렌드"
|
374 |
-
},
|
375 |
-
"셀프러브": {
|
376 |
-
"sub1": "💕 '나 자신과 연애 중'이라고 말할 수 있나요?",
|
377 |
-
"main": "셀프러브는 '셀프'로 '러브'하는 거 맞아! 💖",
|
378 |
-
"sub2": "오늘부터 내가 내 최고의 연인이 되는 거야 ✨",
|
379 |
-
"hashtags": ["#셀프러브", "#나를위한시간", "#갈렌타인", "#솔로라이프"],
|
380 |
-
"reference": "갈렌타인데이, 셀프케어 문화"
|
381 |
-
},
|
382 |
-
"봄맞이": {
|
383 |
-
"sub1": "🌸 '봄이 오네 봄이 와~' 기분이 들죠?",
|
384 |
-
"main": "봄맞이는 '봄'을 '맞'이하는 게 아니라 '맞다'이! 🌱",
|
385 |
-
"sub2": "이번 봄엔 정말 '꽃길'만 걸어보자구요 💐",
|
386 |
-
"hashtags": ["#봄맞이", "#꽃길걷기", "#새시작", "#벚꽃엔딩"],
|
387 |
-
"reference": "봄 관련 트렌드, 꽃길 표현"
|
388 |
-
},
|
389 |
-
"바캉스": {
|
390 |
-
"sub1": "🏖️ '일상 탈출'이 필요한 순간이에요!",
|
391 |
-
"main": "바캉스는 '바'로 떠나서 '캉'스럽게 쉬는 거야! ☀️",
|
392 |
-
"sub2": "올여름엔 진짜 '힐링'이 뭔지 보여주겠어 🌊",
|
393 |
-
"hashtags": ["#바캉스", "#일상탈출", "#힐링여행", "#여름휴가"],
|
394 |
-
"reference": "일상탈출, 힐링 문화"
|
395 |
},
|
396 |
"그린데이": {
|
397 |
"sub1": "💚 '그린'하면 생각나는 게 뭐예요?",
|
398 |
"main": "그린데이는 '그'냥 '린'스하지 말고 새롭게! 💚",
|
399 |
"sub2": "이번 여름엔 '그린'한 추억 만들어요 🌿",
|
400 |
-
"hashtags": ["#그린데이", "#여름추억", "#힐링", "#자연"]
|
401 |
-
"reference": "그린데이, 자연친화 트렌드"
|
402 |
},
|
403 |
-
"
|
404 |
-
"sub1": "
|
405 |
-
"main": "
|
406 |
-
"sub2": "
|
407 |
-
"hashtags": ["
|
408 |
-
"reference": "에모 트렌드, 감성 문화"
|
409 |
}
|
410 |
}
|
411 |
|
412 |
-
#
|
413 |
-
|
414 |
-
"
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
if not period_text or period_text.strip() == "":
|
8 |
return None
|
9 |
|
|
|
10 |
date_patterns = [
|
11 |
+
r'(\d{4})\.(\d{1,2})\.(\d{1,2})',
|
12 |
+
r'(\d{1,2})\.(\d{1,2})',
|
13 |
+
r'(\d{1,2})월',
|
14 |
]
|
15 |
|
16 |
for pattern in date_patterns:
|
17 |
matches = re.findall(pattern, period_text)
|
18 |
if matches:
|
19 |
+
if len(matches[0]) == 3:
|
20 |
month = int(matches[0][1])
|
21 |
+
elif len(matches[0]) == 2:
|
22 |
month = int(matches[0][0])
|
23 |
+
else:
|
24 |
month = int(matches[0])
|
25 |
|
26 |
if 1 <= month <= 12:
|
|
|
31 |
def analyze_concepts(month):
|
32 |
"""20-40대 여성 맞춤 월별 컨셉 분석"""
|
33 |
|
|
|
34 |
monthly_data = {
|
35 |
"1월": {
|
|
|
36 |
"special_days": ["미니멀 챌린지", "새해 리셋", "플래너 스타트"],
|
37 |
+
"trends": ["미니멀", "자기계발", "플래너", "정리정돈"],
|
|
|
|
|
38 |
"colors": ["#FF6B6B", "#4ECDC4", "#45B7D1"],
|
39 |
"mood": "희망적이고 새로운 시작",
|
40 |
+
"female_appeal": ["미니멀", "자기계발", "셀프케어"]
|
41 |
},
|
42 |
"2월": {
|
|
|
43 |
"special_days": ["갈렌타인데이", "셀프러브", "사랑의 달"],
|
44 |
+
"trends": ["셀프러브", "갈렌타인", "로맨스", "따뜻한 감성"],
|
|
|
|
|
45 |
"colors": ["#FF69B4", "#FFB6C1", "#DC143C"],
|
46 |
"mood": "로맨틱하고 감성적",
|
47 |
+
"female_appeal": ["셀프러브", "우정", "로맨스"]
|
48 |
},
|
49 |
"3월": {
|
|
|
50 |
"special_days": ["여성의 날", "봄의 시작", "새학기"],
|
51 |
+
"trends": ["봄맞이", "벚꽃 시즌", "봄 패션", "새출발"],
|
|
|
|
|
52 |
"colors": ["#FFB6C1", "#98FB98", "#87CEEB"],
|
53 |
"mood": "설렘가득하고 활기찬",
|
54 |
+
"female_appeal": ["봄 패션", "꽃구경", "새출발"]
|
55 |
},
|
56 |
"4월": {
|
|
|
57 |
"special_days": ["벚꽃 시즌", "봄나들이", "피크닉"],
|
58 |
+
"trends": ["벚꽃축제", "봄피크닉", "아웃도어", "꽃놀이"],
|
|
|
|
|
59 |
"colors": ["#98FB98", "#F0E68C", "#DDA0DD"],
|
60 |
"mood": "생기발랄하고 즐거운",
|
61 |
+
"female_appeal": ["벚꽃놀이", "피크닉", "봄여행"]
|
62 |
},
|
63 |
"5월": {
|
64 |
+
"special_days": ["로즈데이", "감사의 달", "힐링"],
|
65 |
+
"trends": ["감사", "나들이", "로즈데이", "봄여행"],
|
|
|
|
|
|
|
66 |
"colors": ["#32CD32", "#FFB6C1", "#87CEEB"],
|
67 |
"mood": "따뜻하고 감사한",
|
68 |
+
"female_appeal": ["로즈데이", "감사표현", "힐링"]
|
69 |
},
|
70 |
"6월": {
|
71 |
+
"special_days": ["키스데이", "여름 준비", "쿨링"],
|
72 |
+
"trends": ["여름준비", "쿨링", "바캉스준비", "여름패션"],
|
|
|
|
|
|
|
73 |
"colors": ["#00CED1", "#FFD700", "#FF6347"],
|
74 |
"mood": "시원하고 활동적인",
|
75 |
+
"female_appeal": ["여름준비", "쿨링케어", "바캉스"]
|
76 |
},
|
77 |
"7월": {
|
|
|
78 |
"special_days": ["실버데이", "여름휴가", "바캉스"],
|
79 |
+
"trends": ["여름휴가", "바캉스", "휴가패션", "여행"],
|
|
|
|
|
80 |
"colors": ["#00BFFF", "#FFD700", "#FF6347"],
|
81 |
"mood": "역동적이고 자유로운",
|
82 |
+
"female_appeal": ["바캉스", "여행", "휴가패션"]
|
83 |
},
|
84 |
"8월": {
|
|
|
85 |
"special_days": ["그린데이", "여름 마무리", "휴가"],
|
86 |
+
"trends": ["여름휴가", "바다여행", "축제", "여름추억"],
|
|
|
|
|
87 |
"colors": ["#00BFFF", "#FF6347", "#FFD700"],
|
88 |
"mood": "열정적이고 추억가득한",
|
89 |
+
"female_appeal": ["여름추억", "힐링", "여행"]
|
90 |
},
|
91 |
"9월": {
|
|
|
92 |
"special_days": ["포토데이", "뮤직데이", "가을시작"],
|
93 |
+
"trends": ["가을패션", "독서", "문화생활", "감성"],
|
|
|
|
|
94 |
"colors": ["#FF8C00", "#DC143C", "#B8860B"],
|
95 |
"mood": "감성적이고 성숙한",
|
96 |
+
"female_appeal": ["가을패션", "카페", "독서"]
|
97 |
},
|
98 |
"10월": {
|
|
|
99 |
"special_days": ["와인데이", "커피데이", "독서의 달"],
|
100 |
+
"trends": ["가을단풍", "독서", "카페문화", "와인"],
|
|
|
|
|
101 |
"colors": ["#FF8C00", "#DC143C", "#B8860B"],
|
102 |
"mood": "감성적이고 여유로운",
|
103 |
+
"female_appeal": ["단풍구경", "카페", "와인"]
|
104 |
},
|
105 |
"11월": {
|
|
|
106 |
"special_days": ["무비데이", "오렌지데이", "연말준비"],
|
107 |
+
"trends": ["빼빼로데이", "연말준비", "겨울패션", "따뜻함"],
|
|
|
|
|
108 |
"colors": ["#8B4513", "#A0522D", "#CD853F"],
|
109 |
"mood": "포근하고 준비하는",
|
110 |
+
"female_appeal": ["빼빼로데이", "겨울패션", "연말모임"]
|
111 |
},
|
112 |
"12월": {
|
|
|
113 |
"special_days": ["허그데이", "연말파티", "송년"],
|
114 |
+
"trends": ["크리스마스", "연말파티", "선물", "송년회"],
|
|
|
|
|
115 |
"colors": ["#DC143C", "#228B22", "#FFD700"],
|
116 |
"mood": "축제같고 따뜻한",
|
117 |
+
"female_appeal": ["크리스마스", "연말모임", "선물"]
|
118 |
}
|
119 |
}
|
120 |
|
121 |
data = monthly_data.get(month, {})
|
122 |
|
|
|
123 |
concepts = []
|
124 |
|
125 |
+
# 컨셉 1
|
126 |
if data.get("special_days"):
|
127 |
special = data["special_days"][0]
|
128 |
concepts.append({
|
129 |
"name": f"{special} 이벤트",
|
130 |
+
"theme": f"{special}를 테마로 한 여성 맞춤 이벤트",
|
131 |
"score": 8.8,
|
132 |
+
"reason": f"20-40대 여성이 공감할 수 있는 {special} 테마",
|
133 |
+
"target": "20-40대 여성",
|
134 |
"colors": data.get("colors", ["#FF69B4"]),
|
135 |
"keywords": [special] + data.get("female_appeal", [])[:2],
|
|
|
136 |
"is_recommended": True
|
137 |
})
|
138 |
|
139 |
+
# 컨셉 2
|
140 |
if data.get("trends"):
|
141 |
trend = data["trends"][0]
|
142 |
concepts.append({
|
143 |
"name": f"{trend} 챌린지",
|
144 |
+
"theme": f"{trend} 트렌드 참여형 이벤트",
|
145 |
+
"score": 8.0,
|
146 |
+
"reason": f"인기 {trend} 트렌드로 높은 관심도",
|
147 |
+
"target": "20-30대 트렌드 민감층",
|
148 |
"colors": data.get("colors", ["#4ECDC4"]),
|
149 |
"keywords": data.get("trends", [])[:3],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
150 |
"is_recommended": False
|
151 |
})
|
152 |
|
153 |
+
# 컨셉 3
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
154 |
concepts.append({
|
155 |
"name": f"{month} 셀프케어 위크",
|
156 |
+
"theme": "나를 위한 특별한 시간",
|
157 |
"score": 8.3,
|
158 |
+
"reason": "셀프케어로 강한 어필",
|
159 |
+
"target": "20-40대 여성",
|
160 |
"colors": data.get("colors", ["#FFB6C1"]),
|
161 |
+
"keywords": ["셀프케어", "힐링", "나를 위한 시간"],
|
|
|
162 |
"is_recommended": True
|
163 |
})
|
164 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
165 |
concepts.sort(key=lambda x: (x.get("is_recommended", False), x["score"]), reverse=True)
|
166 |
|
|
|
167 |
recommended_concept = next((c for c in concepts if c.get("is_recommended", False)), concepts[0])
|
168 |
|
|
|
169 |
result = f"# 🎯 {month} 20-40대 여성 맞춤 컨셉 분석\n\n"
|
170 |
result += f"## 🏆 이달의 추천 컨셉: {recommended_concept['name']}\n"
|
171 |
result += f"**⭐ 추천 이유:** {recommended_concept['reason']}\n"
|
172 |
result += f"**📊 예상 참여도:** {recommended_concept['score']}/10점\n\n"
|
173 |
result += "---\n\n"
|
174 |
|
|
|
|
|
|
|
|
|
|
|
175 |
concept_names = []
|
176 |
|
177 |
for i, concept in enumerate(concepts, 1):
|
|
|
182 |
result += f"**💡 선정 이유:** {concept['reason']}\n"
|
183 |
result += f"**🎯 주요 타겟:** {concept['target']}\n"
|
184 |
result += f"**🔑 핵심 키워드:** {', '.join(concept['keywords'])}\n"
|
|
|
185 |
result += f"**🎨 추천 색상:** {', '.join(concept['colors'])}\n\n"
|
186 |
result += "---\n\n"
|
187 |
|
188 |
concept_names.append(concept['name'])
|
189 |
|
|
|
|
|
|
|
|
|
190 |
return result, concept_names
|
191 |
|
192 |
def generate_design_recommendations(concept_name, month):
|
193 |
+
"""디자인 추천"""
|
194 |
|
195 |
design_styles = {
|
196 |
+
"미니멀": ["심플 미니멀 디자인", "깔끔한 선과 여백을 활용"],
|
197 |
+
"네온사인": ["레트로 네온사인 스타일", "80년대 네온사인 화려함"],
|
198 |
+
"Y2K": ["Y2K 레트로 퓨처", "2000년대 미래적 감성"],
|
199 |
+
"게임UI": ["게임 인터페이스", "RPG 게임 UI 모티브"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
}
|
201 |
|
|
|
202 |
monthly_design = {
|
203 |
+
"1월": ["미니멀", "Y2K"], "2월": ["미니멀", "네온사인"],
|
204 |
+
"3월": ["네온사인", "Y2K"], "4월": ["네온사인", "Y2K"],
|
205 |
+
"5월": ["미니멀", "네온사인"], "6월": ["네온사인", "Y2K"],
|
206 |
"7월": ["Y2K", "네온사인"], "8월": ["Y2K", "게임UI"],
|
207 |
+
"9월": ["미니멀", "네온사인"], "10월": ["미니멀", "네온사인"],
|
208 |
+
"11월": ["미니멀", "네온사인"], "12월": ["네온사인", "게임UI"]
|
209 |
}
|
210 |
|
211 |
month_key = month.replace('월', '월')
|
212 |
+
recommended_designs = monthly_design.get(month_key, ["미니멀", "네온사인"])
|
213 |
|
214 |
result = "## 🎨 추천 디자인 스타일\n\n"
|
215 |
|
216 |
for i, design_key in enumerate(recommended_designs, 1):
|
217 |
+
if design_key in design_styles:
|
218 |
+
style_name, description = design_styles[design_key]
|
219 |
+
result += f"### {i}. {style_name} 🌟\n"
|
220 |
+
result += f"**설명:** {description}\n\n"
|
|
|
|
|
221 |
|
222 |
return result
|
223 |
|
224 |
+
def generate_trendy_copy(concept_name, month):
|
225 |
+
"""트렌디한 카피라이팅 생성"""
|
226 |
|
|
|
227 |
trendy_copies = {
|
228 |
"미니멀": {
|
229 |
"sub1": "🌟 '나는 정리를 못하는 여자'는 이제 그만!",
|
230 |
"main": "미니멀은 '미'니로 '말'하는 거야, 작게 말해도 큰 변화! ✨",
|
231 |
"sub2": "올해는 진짜 '갓생'을 살아보자구요! 💪",
|
232 |
+
"hashtags": ["#갓생살기", "#미니멀", "#정리의신", "#새해정리"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
233 |
},
|
234 |
"그린데이": {
|
235 |
"sub1": "💚 '그린'하면 생각나는 게 뭐예요?",
|
236 |
"main": "그린데이는 '그'냥 '린'스하지 말고 새롭게! 💚",
|
237 |
"sub2": "이번 여름엔 '그린'한 추억 만들어요 🌿",
|
238 |
+
"hashtags": ["#그린데이", "#여름추억", "#힐링", "#자연"]
|
|
|
239 |
},
|
240 |
+
"셀프케어": {
|
241 |
+
"sub1": "💕 '나 자신과 연애 중'이라고 말할 수 있나요?",
|
242 |
+
"main": "셀프케어는 '셀프'로 '케어'하는 거 맞아! 💖",
|
243 |
+
"sub2": "오늘부터 내가 내 최고의 친구가 되는 거야 ✨",
|
244 |
+
"hashtags": ["#셀프케어", "#나를위한시간", "#힐링", "#자기사랑"]
|
|
|
245 |
}
|
246 |
}
|
247 |
|
248 |
+
# 기본 카피
|
249 |
+
default_copy = {
|
250 |
+
"sub1": "✨ 이런 특별한 순간을 놓칠 수 없죠!",
|
251 |
+
"main": "지금 이 순간이 바로 '찐'이야! 💫",
|
252 |
+
"sub2": "함께라면 뭐든 '레전드'가 될 수 있어요 🎉",
|
253 |
+
"hashtags": ["#찐이야", "#레전드순간", "#함께해요", "#특별한시간"]
|
254 |
+
}
|
255 |
+
|
256 |
+
# 컨셉명에서 키워드 찾기
|
257 |
+
for keyword, copy_data in trendy_copies.items():
|
258 |
+
if keyword in concept_name:
|
259 |
+
return copy_data
|
260 |
+
|
261 |
+
return default_copy
|
262 |
+
|
263 |
+
def generate_notice(concept, event_type, event_period, prize_benefits):
|
264 |
+
"""공지사항 생성"""
|
265 |
+
|
266 |
+
if not concept:
|
267 |
+
return "먼저 컨셉을 선택해주세요."
|
268 |
+
|
269 |
+
# 이벤트 기간 설정
|
270 |
+
if not event_period or event_period.strip() == "":
|
271 |
+
now = datetime.now()
|
272 |
+
start_date = now.strftime("%Y.%m.%d")
|
273 |
+
end_date = f"{now.year}.{now.month}.{now.day + 7}"
|
274 |
+
period_text = f"{start_date} ~ {end_date}"
|
275 |
+
else:
|
276 |
+
period_text = event_period
|
277 |
+
|
278 |
+
# 월 추출
|
279 |
+
month = extract_month_from_period(period_text)
|
280 |
+
if not month:
|
281 |
+
month = f"{datetime.now().month}월"
|
282 |
+
|
283 |
+
# 카피 생성
|
284 |
+
copy_data = generate_trendy_copy(concept, month)
|
285 |
+
|
286 |
+
# 디자인 추천
|
287 |
+
design_recommendations = generate_design_recommendations(concept, month)
|
288 |
+
|
289 |
+
# 당첨 혜택 설정
|
290 |
+
if not prize_benefits or prize_benefits.strip() == "":
|
291 |
+
benefits_text = """✨ 1등 (1명): 스타벅스 5만원 기프트카드
|
292 |
+
🎉 2등 (3명): 베스킨라빈스 아이스크림 쿠폰
|
293 |
+
💝 3등 (10명): 편의점 5천원 상품권
|
294 |
+
🌟 참가상 (50명): 모바일 치킨 쿠폰"""
|
295 |
+
else:
|
296 |
+
benefits_text = prize_benefits
|
297 |
+
|
298 |
+
# 해시태그
|
299 |
+
hashtags_text = " ".join(copy_data['hashtags'])
|
300 |
+
|
301 |
+
notice = f"""{copy_data['sub1']}
|
302 |
+
|
303 |
+
💫 {copy_data['main']} 💫
|
304 |
+
|
305 |
+
{copy_data['sub2']}
|
306 |
+
|
307 |
+
🎉 {concept} 🎉
|
308 |
+
|
309 |
+
📅 이벤트 기간: {period_text} 23:59
|
310 |
+
|
311 |
+
{hashtags_text}
|
312 |
+
|
313 |
+
{design_recommendations}
|
314 |
+
|
315 |
+
========================
|
316 |
+
✨ EVENT
|
317 |
+
특별한 {concept}을 준비했어요!
|
318 |
+
많은 분들의 적극적인 참여를 기다리고 있습니다 💕
|
319 |
+
|
320 |
+
이번 이벤트는 단순한 참여가 아닌,
|
321 |
+
우리만의 특별한 추억을 만들어가는 시간이에요 ✨
|
322 |
+
========================
|
323 |
+
|
324 |
+
🎯 참여 방법
|
325 |
+
1️⃣ 이벤트 내용 확인하기
|
326 |
+
2️⃣ {event_type} 참여하기
|
327 |
+
3️⃣ 참여 완료!
|
328 |
+
|
329 |
+
=================
|
330 |
+
🎁 당첨혜택
|
331 |
+
{benefits_text}
|
332 |
+
|
333 |
+
📋 추첨: 참여자 중 무작위 추첨
|
334 |
+
========================
|
335 |
+
|
336 |
+
👥 이벤트 대상
|
337 |
+
✅ 커뮤니티 회원
|
338 |
+
✅ 만 18세 이상
|
339 |
+
✅ 이벤트 기간 내 참여자
|
340 |
+
========================
|
341 |
+
|
342 |
+
⚠️ 주의사항
|
343 |
+
※ 부적절한 참여는 제외됩니다
|
344 |
+
※ 중복 참여 불가
|
345 |
+
※ 당첨자는 본인 확인 필요
|
346 |
+
|
347 |
+
===========================
|
348 |
+
📞 문의: 1234-5678
|
349 |
+
💬 카카오톡: @event_community
|
350 |
+
|
351 |
+
{hashtags_text}
|
352 |
+
|
353 |
+
💝 많은 참여 부탁드려요! 감사합니다 💝"""
|
354 |
+
|
355 |
+
return notice
|
356 |
+
|
357 |
+
def create_interface():
|
358 |
+
"""그라디오 인터페이스 생성"""
|
359 |
+
|
360 |
+
with gr.Blocks(title="이벤트 공지사항 생성기") as demo:
|
361 |
+
|
362 |
+
gr.Markdown("# 🎉 이벤트 공지사항 생성기")
|
363 |
+
gr.Markdown("### 20-40대 여성 맞춤 트렌디한 이벤트를 만들어보세요!")
|
364 |
+
|
365 |
+
with gr.Row():
|
366 |
+
with gr.Column():
|
367 |
+
gr.Markdown("## 설정")
|
368 |
+
|
369 |
+
event_period_input = gr.Textbox(
|
370 |
+
label="이벤트 기간",
|
371 |
+
placeholder="예: 2025.8.1 ~ 2025.8.10",
|
372 |
+
info="이벤트 기간을 입력하면 해당 월이 자동으로 선택됩니다"
|
373 |
+
)
|
374 |
+
|
375 |
+
month_dropdown = gr.Dropdown(
|
376 |
+
choices=[f"{i}월" for i in range(1, 13)],
|
377 |
+
label="이벤트 월 선택",
|
378 |
+
value="1월"
|
379 |
+
)
|
380 |
+
|
381 |
+
analyze_btn = gr.Button("컨셉 분석하기", variant="primary")
|
382 |
+
|
383 |
+
concept_dropdown = gr.Dropdown(
|
384 |
+
label="컨셉 선택",
|
385 |
+
visible=False
|
386 |
+
)
|
387 |
+
|
388 |
+
event_type_dropdown = gr.Dropdown(
|
389 |
+
choices=["댓글 달기", "게시글 작성", "좋아요 누르기"],
|
390 |
+
label="이벤트 유형",
|
391 |
+
value="댓글 달기"
|
392 |
+
)
|
393 |
+
|
394 |
+
gr.Markdown("## 🎁 당첨 혜택 설정")
|
395 |
+
|
396 |
+
prize_benefits_input = gr.Textbox(
|
397 |
+
label="당첨 혜택",
|
398 |
+
placeholder="당첨 혜택을 입력하세요 (비워두면 기본 혜택 적용)",
|
399 |
+
lines=6
|
400 |
+
)
|
401 |
+
|
402 |
+
generate_btn = gr.Button("공지사항 생성하기", variant="secondary", visible=False)
|
403 |
+
|
404 |
+
with gr.Column():
|
405 |
+
gr.Markdown("## 결과")
|
406 |
+
|
407 |
+
concept_output = gr.Textbox(
|
408 |
+
label="컨셉 분석 결과",
|
409 |
+
lines=20,
|
410 |
+
placeholder="먼저 '컨셉 분석하기' 버튼을 클릭하세요"
|
411 |
+
)
|
412 |
+
|
413 |
+
notice_output = gr.Textbox(
|
414 |
+
label="생성된 공지사항",
|
415 |
+
lines=25,
|
416 |
+
placeholder="컨셉을 선택하고 '공지사항 생성하기' 버튼을 클릭하세요"
|
417 |
+
)
|
418 |
+
|
419 |
+
# 상태 변수
|
420 |
+
concepts_state = gr.State([])
|
421 |
+
selected_concept_state = gr.State("")
|
422 |
+
|
423 |
+
def handle_period_change(period_text):
|
424 |
+
detected_month = extract_month_from_period(period_text)
|
425 |
+
if detected_month:
|
426 |
+
return gr.update(value=detected_month)
|
427 |
+
return gr.update()
|
428 |
+
|
429 |
+
def handle_analyze(month):
|
430 |
+
result, concepts = analyze_concepts(month)
|
431 |
+
return (
|
432 |
+
result,
|
433 |
+
gr.update(choices=concepts, visible=True, value=concepts[0]),
|
434 |
+
gr.update(visible=True),
|
435 |
+
concepts
|
436 |
+
)
|
437 |
+
|
438 |
+
def handle_concept_change(concept, concepts):
|
439 |
+
return concept
|
440 |
+
|
441 |
+
def handle_generate(concept, event_type, event_period, prize_benefits):
|
442 |
+
notice = generate_notice(concept, event_type, event_period, prize_benefits)
|
443 |
+
return notice
|
444 |
+
|
445 |
+
# 이벤트 연결
|
446 |
+
event_period_input.change(
|
447 |
+
handle_period_change,
|
448 |
+
inputs=[event_period_input],
|
449 |
+
outputs=[month_dropdown]
|
450 |
+
)
|
451 |
+
|
452 |
+
analyze_btn.click(
|
453 |
+
handle_analyze,
|
454 |
+
inputs=[month_dropdown],
|
455 |
+
outputs=[concept_output, concept_dropdown, generate_btn, concepts_state]
|
456 |
+
)
|
457 |
+
|
458 |
+
concept_dropdown.change(
|
459 |
+
handle_concept_change,
|
460 |
+
inputs=[concept_dropdown, concepts_state],
|
461 |
+
outputs=[selected_concept_state]
|
462 |
+
)
|
463 |
+
|
464 |
+
generate_btn.click(
|
465 |
+
handle_generate,
|
466 |
+
inputs=[selected_concept_state, event_type_dropdown, event_period_input, prize_benefits_input],
|
467 |
+
outputs=[notice_output]
|
468 |
+
)
|
469 |
+
|
470 |
+
return demo
|
471 |
+
|
472 |
+
if __name__ == "__main__":
|
473 |
+
demo = create_interface()
|
474 |
+
demo.launch()
|