aliceblue11 commited on
Commit
16db0bd
·
verified ·
1 Parent(s): d4d64af

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +297 -245
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})', # 2024.12.01
13
- r'(\d{1,2})\.(\d{1,2})', # 12.01
14
- r'(\d{1,2})월', # 12월
15
  ]
16
 
17
  for pattern in date_patterns:
18
  matches = re.findall(pattern, period_text)
19
  if matches:
20
- if len(matches[0]) == 3: # YYYY.MM.DD
21
  month = int(matches[0][1])
22
- elif len(matches[0]) == 2: # MM.DD
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
- "seasonal_terms": ["소한", "대한", "입춘"],
41
- "trends": ["미니멀", "자기계발", "플래너", "정리정돈", "헬스케어", "독서"],
42
- "seasons": ["겨울", "신년", "새로운 시작"],
43
  "colors": ["#FF6B6B", "#4ECDC4", "#45B7D1"],
44
  "mood": "희망적이고 새로운 시작",
45
- "female_appeal": ["미니멀", "자기계발", "셀프케어", "새해다짐"]
46
  },
47
  "2월": {
48
- "holidays": ["밸런타인데이"],
49
  "special_days": ["갈렌타인데이", "셀프러브", "사랑의 달"],
50
- "seasonal_terms": ["입춘", "우수"],
51
- "trends": ["셀프러브", "갈렌타인", "로맨스", "따뜻한 감성", "핑크 무드"],
52
- "seasons": ["겨울 끝", "봄 준비", "로맨틱"],
53
  "colors": ["#FF69B4", "#FFB6C1", "#DC143C"],
54
  "mood": "로맨틱하고 감성적",
55
- "female_appeal": ["셀프러브", "우정", "로맨스", "감성"]
56
  },
57
  "3월": {
58
- "holidays": ["삼일절", "화이트데이"],
59
  "special_days": ["여성의 날", "봄의 시작", "새학기"],
60
- "seasonal_terms": ["경칩", "춘분"],
61
- "trends": ["봄맞이", "벚꽃 시즌", "봄 패션", "새출발", "꽃구경"],
62
- "seasons": ["봄", "벚꽃", "새싹"],
63
  "colors": ["#FFB6C1", "#98FB98", "#87CEEB"],
64
  "mood": "설렘가득하고 활기찬",
65
- "female_appeal": ["봄 패션", "꽃구경", "새출발", "여성의 날"]
66
  },
67
  "4월": {
68
- "holidays": ["만우절"],
69
  "special_days": ["벚꽃 시즌", "봄나들이", "피크닉"],
70
- "seasonal_terms": ["청명", "곡우"],
71
- "trends": ["벚꽃축제", "봄피크닉", "아웃도어", "꽃놀이", "봄여행"],
72
- "seasons": ["봄 절정", "꽃구경", "나들이"],
73
  "colors": ["#98FB98", "#F0E68C", "#DDA0DD"],
74
  "mood": "생기발랄하고 즐거운",
75
- "female_appeal": ["벚꽃놀이", "피크닉", "봄여행", "감성사진"]
76
  },
77
  "5월": {
78
- "holidays": ["근로자의날"],
79
- "special_days": ["로즈데이", "가정의 달", "감사의 "],
80
- "seasonal_terms": ["입하", "소만"],
81
- "trends": ["감사", "나들이", "로즈데이", "봄여행", "힐링"],
82
- "seasons": ["신록", "야외활동", "따뜻함"],
83
  "colors": ["#32CD32", "#FFB6C1", "#87CEEB"],
84
  "mood": "따뜻하고 감사한",
85
- "female_appeal": ["로즈데이", "감사표현", "힐링", "나들이"]
86
  },
87
  "6월": {
88
- "holidays": ["현충일"],
89
- "special_days": ["키스데이", "여름 준비", "��이어트"],
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
- "seasonal_terms": ["소서", "대서", "초복", "중복"],
101
- "trends": ["여름휴가", "바캉스", "휴가패션", "여행", "힐링"],
102
- "seasons": ["여름", "휴가", "바캉스"],
103
  "colors": ["#00BFFF", "#FFD700", "#FF6347"],
104
  "mood": "역동적이고 자유로운",
105
- "female_appeal": ["바캉스", "여행", "휴가패션", "힐링"]
106
  },
107
  "8월": {
108
- "holidays": ["광복절"],
109
  "special_days": ["그린데이", "여름 마무리", "휴가"],
110
- "seasonal_terms": ["입추", "처서", "말복"],
111
- "trends": ["여름휴가", "바다여행", "축제", "여름추억", "힐링"],
112
- "seasons": ["한여름", "휴가절정", "추억"],
113
  "colors": ["#00BFFF", "#FF6347", "#FFD700"],
114
  "mood": "열정적이고 추억가득한",
115
- "female_appeal": ["여름추억", "힐링", "여행", "감성사진"]
116
  },
117
  "9월": {
118
- "holidays": ["추석"],
119
  "special_days": ["포토데이", "뮤직데이", "가을시작"],
120
- "seasonal_terms": ["백로", "추분"],
121
- "trends": ["가을패션", "독서", "문화생활", "감성", "카페"],
122
- "seasons": ["가을", "선선함", "감성"],
123
  "colors": ["#FF8C00", "#DC143C", "#B8860B"],
124
  "mood": "감성적이고 성숙한",
125
- "female_appeal": ["가을패션", "카페", "독서", "감성사진"]
126
  },
127
  "10월": {
128
- "holidays": ["한글날"],
129
  "special_days": ["와인데이", "커피데이", "독서의 달"],
130
- "seasonal_terms": ["한로", "상강"],
131
- "trends": ["가을단풍", "독서", "카페문화", "와인", "감성"],
132
- "seasons": ["단풍", "가을정취", "감성"],
133
  "colors": ["#FF8C00", "#DC143C", "#B8860B"],
134
  "mood": "감성적이고 여유로운",
135
- "female_appeal": ["단풍구경", "카페", "와인", "독서"]
136
  },
137
  "11월": {
138
- "holidays": ["빼빼로데이"],
139
  "special_days": ["무비데이", "오렌지데이", "연말준비"],
140
- "seasonal_terms": ["입동", "소설"],
141
- "trends": ["빼빼로데이", "연말준비", "겨울패션", "따뜻함", "코지"],
142
- "seasons": ["늦가을", "겨울준비", "포근함"],
143
  "colors": ["#8B4513", "#A0522D", "#CD853F"],
144
  "mood": "포근하고 준비하는",
145
- "female_appeal": ["빼빼로데이", "겨울패션", "연말모임", "코지"]
146
  },
147
  "12월": {
148
- "holidays": ["크리스마스"],
149
  "special_days": ["허그데이", "연말파티", "송년"],
150
- "seasonal_terms": ["대설", "동지"],
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}를 테마로 한 20-40대 여성 맞춤 이벤트",
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"20-40대 여성 트렌드 {trend} 참여형 이벤트",
185
- "score": 8.5,
186
- "reason": f"현재 여성층에게 인기 있는 {trend} 트렌드로 높은 관심도",
187
- "target": "20-30대 트렌드 민감층, SNS 활용 여성",
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
- # 컨셉 4: 계절감 + 여성 어필 기반
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": "20-40대 여성의 핵심 관심사인 셀프케어로 강한 어필",
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
- "style": "심플 미니멀 디자인",
296
- "description": "깔끔한 선과 여백을 활용한 세련된 디자인",
297
- "engagement": "차분하면서도 고급스러운 느낌으로 신뢰감 상승",
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월": ["손그��", "코어"], "4월": ["손그림", "네온사인"],
342
- "5월": ["코어", "손그림"], "6월": ["네온사인", "Y2K"],
343
  "7월": ["Y2K", "네온사인"], "8월": ["Y2K", "게임UI"],
344
- "9월": ["코어", "미니멀"], "10월": ["코어", "손그림"],
345
- "11월": ["미니멀", "손그림"], "12월": ["네온사인", "게임UI"]
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
- design = design_styles[design_key]
355
- result += f"### {i}. {design['style']} 🌟\n"
356
- result += f"**설명:** {design['description']}\n"
357
- result += f"**참여도 효과:** {design['engagement']}\n"
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, event_period):
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
- seasonal_copies = {
414
- "1월": {
415
- "sub1": "🌟 '새해 새마음'이라는 말이 괜히 있는 게 아니야",
416
- "main": "2025년은 '이십이오'라고 읽으면 '이십이 오'케이! ",
417
- "sub2": "올해는 정말 '레전드 한 해'가 될 거예요 🚀",
418
- "hashtags": ["#새해새마음", "#2025레전드", "#갓생예약", "#새출발"],
419
- "reference": "새해 다짐 문화"
420
- },
421
- "8월": {
422
- "sub1": "🏖️ '일상 탈출'이 필요한 순간이에요!",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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()